
// http://patik.com/blog/complete-cross-browser-console-log/

// Tell IE9 to use its built-in console
// huy 2012-05-18 `bind` is defined in our code somewhere.  So that's not reliable detection
//if (Function.prototype.bind && console && typeof console.log == "object") {
if (document.getElementsByClassName && Function.prototype.bind && typeof console !== 'undefined' && typeof console.log == "object") {
        ["log","info","warn","error","assert","dir","clear","profile","profileEnd"]
                .forEach(function (method) {
                        console[method] = this.call(console[method], console);
                }, Function.prototype.bind);
}

// log() -- The complete, cross-browser (we don't judge!) console.log wrapper for his or her logging pleasure
if (!window.log) {
        window.log = function () {
                log.history = log.history || [];  // store logs to an array for reference
                log.history.push(arguments);

                // Modern browsers
                if (typeof console != 'undefined' && typeof console.log == 'function') {
                        
                        // Opera 11
                        if (window.opera) {
                                var i = 0;
                                while (i < arguments.length) {
                                        console.log("Item " + (i+1) + ": " + arguments[i]);
                                        i++;
                                }
                        }
                        
                        // All other modern browsers
                        else if ((Array.prototype.slice.call(arguments)).length === 1 && typeof Array.prototype.slice.call(arguments)[0] === 'string') {
                                console.log( (Array.prototype.slice.call(arguments)).toString() );
                        }
                        else {
                                console.log( Array.prototype.slice.call(arguments) );
                        }
                        
                }
                
                // IE8
                // huy 2012-05-18 `bind` is defined in our code somewhere.  So that's not reliable detection
                //else if (!Function.prototype.bind && typeof console != 'undefined' && typeof console.log == 'object') {
                else if (document.querySelector && !document.getElementsByClassName && typeof console != 'undefined' && typeof console.log == 'object') {
                        Function.prototype.call.call(console.log, console, Array.prototype.slice.call(arguments));
                }
                
                // IE7 and lower, and other old browsers
                else {
                        // Inject Firebug lite
                        if (!document.getElementById('firebug-lite')) {
                                // Include the script
                                var script = document.createElement('script');
                                script.type = "text/javascript";
                                script.id = 'firebug-lite';
                                // If you run the script locally, point to /path/to/firebug-lite/build/firebug-lite.js
                                script.src = '//getfirebug.com/firebug-lite.js';
                                // If you want to expand the console window by default, uncomment this line
                                //document.getElementsByTagName('HTML')[0].setAttribute('debug','true');
                                document.getElementsByTagName('HEAD')[0].appendChild(script);
                                setTimeout(function () { log( Array.prototype.slice.call(arguments) ); }, 2000);
                        }
                        else {
                                // FBL was included but it hasn't finished loading yet, so try again momentarily
                                setTimeout(function () { log( Array.prototype.slice.call(arguments) ); }, 500);
                        }
                }
        }
}
;
define("log", (function (global) {
    return function () {
        var ret, fn;
        return ret || global.window.log;
    };
}(this)));

(function(){function e(t,i,a){if(t===i)return 0!==t||1/t==1/i;if(null==t||null==i)return t===i;if(t._chain&&(t=t._wrapped),i._chain&&(i=i._wrapped),t.isEqual&&j.isFunction(t.isEqual))return t.isEqual(i);if(i.isEqual&&j.isFunction(i.isEqual))return i.isEqual(t);var o=u.call(t);if(o!=u.call(i))return!1;switch(o){case"[object String]":return t==i+"";case"[object Number]":return t!=+t?i!=+i:0==t?1/t==1/i:t==+i;case"[object Date]":case"[object Boolean]":return+t==+i;case"[object RegExp]":return t.source==i.source&&t.global==i.global&&t.multiline==i.multiline&&t.ignoreCase==i.ignoreCase}if("object"!=typeof t||"object"!=typeof i)return!1;for(var s=a.length;s--;)if(a[s]==t)return!0;a.push(t);var n=0,r=!0;if("[object Array]"==o){if(n=t.length,r=n==i.length)for(;n--&&(r=n in t==n in i&&e(t[n],i[n],a)););}else{if("constructor"in t!="constructor"in i||t.constructor!=i.constructor)return!1;for(var l in t)if(j.has(t,l)&&(n++,!(r=j.has(i,l)&&e(t[l],i[l],a))))break;if(r){for(l in i)if(j.has(i,l)&&!n--)break;r=!n}}return a.pop(),r}var t=this,i=t._,a={},o=Array.prototype,s=Object.prototype,n=Function.prototype,r=o.slice,l=o.unshift,u=s.toString,c=s.hasOwnProperty,d=o.forEach,p=o.map,h=o.reduce,f=o.reduceRight,m=o.filter,g=o.every,v=o.some,b=o.indexOf,y=o.lastIndexOf,w=Array.isArray,k=Object.keys,_=n.bind,j=function(e){return new P(e)};"undefined"!=typeof exports?("undefined"!=typeof module&&module.exports&&(exports=module.exports=j),exports._=j):t._=j,j.VERSION="1.3.1";var x=j.each=j.forEach=function(e,t,i){if(null!=e)if(d&&e.forEach===d)e.forEach(t,i);else if(e.length===+e.length){for(var o=0,s=e.length;s>o;o++)if(o in e&&t.call(i,e[o],o,e)===a)return}else for(var n in e)if(j.has(e,n)&&t.call(i,e[n],n,e)===a)return};j.map=j.collect=function(e,t,i){var a=[];return null==e?a:p&&e.map===p?e.map(t,i):(x(e,function(e,o,s){a[a.length]=t.call(i,e,o,s)}),e.length===+e.length&&(a.length=e.length),a)},j.reduce=j.foldl=j.inject=function(e,t,i,a){var o=arguments.length>2;if(null==e&&(e=[]),h&&e.reduce===h)return a&&(t=j.bind(t,a)),o?e.reduce(t,i):e.reduce(t);if(x(e,function(e,s,n){o?i=t.call(a,i,e,s,n):(i=e,o=!0)}),!o)throw new TypeError("Reduce of empty array with no initial value");return i},j.reduceRight=j.foldr=function(e,t,i,a){var o=arguments.length>2;if(null==e&&(e=[]),f&&e.reduceRight===f)return a&&(t=j.bind(t,a)),o?e.reduceRight(t,i):e.reduceRight(t);var s=j.toArray(e).reverse();return a&&!o&&(t=j.bind(t,a)),o?j.reduce(s,t,i,a):j.reduce(s,t)},j.find=j.detect=function(e,t,i){var a;return A(e,function(e,o,s){return t.call(i,e,o,s)?(a=e,!0):void 0}),a},j.filter=j.select=function(e,t,i){var a=[];return null==e?a:m&&e.filter===m?e.filter(t,i):(x(e,function(e,o,s){t.call(i,e,o,s)&&(a[a.length]=e)}),a)},j.reject=function(e,t,i){var a=[];return null==e?a:(x(e,function(e,o,s){t.call(i,e,o,s)||(a[a.length]=e)}),a)},j.every=j.all=function(e,t,i){var o=!0;return null==e?o:g&&e.every===g?e.every(t,i):(x(e,function(e,s,n){return(o=o&&t.call(i,e,s,n))?void 0:a}),o)};var A=j.some=j.any=function(e,t,i){t||(t=j.identity);var o=!1;return null==e?o:v&&e.some===v?e.some(t,i):(x(e,function(e,s,n){return o||(o=t.call(i,e,s,n))?a:void 0}),!!o)};j.include=j.contains=function(e,t){var i=!1;return null==e?i:b&&e.indexOf===b?-1!=e.indexOf(t):i=A(e,function(e){return e===t})},j.invoke=function(e,t){var i=r.call(arguments,2);return j.map(e,function(e){return(j.isFunction(t)?t||e:e[t]).apply(e,i)})},j.pluck=function(e,t){return j.map(e,function(e){return e[t]})},j.max=function(e,t,i){if(!t&&j.isArray(e))return Math.max.apply(Math,e);if(!t&&j.isEmpty(e))return-1/0;var a={computed:-1/0};return x(e,function(e,o,s){var n=t?t.call(i,e,o,s):e;n>=a.computed&&(a={value:e,computed:n})}),a.value},j.min=function(e,t,i){if(!t&&j.isArray(e))return Math.min.apply(Math,e);if(!t&&j.isEmpty(e))return 1/0;var a={computed:1/0};return x(e,function(e,o,s){var n=t?t.call(i,e,o,s):e;a.computed>n&&(a={value:e,computed:n})}),a.value},j.shuffle=function(e){var t,i=[];return x(e,function(e,a){0==a?i[0]=e:(t=Math.floor(Math.random()*(a+1)),i[a]=i[t],i[t]=e)}),i},j.sortBy=function(e,t,i){return j.pluck(j.map(e,function(e,a,o){return{value:e,criteria:t.call(i,e,a,o)}}).sort(function(e,t){var i=e.criteria,a=t.criteria;return a>i?-1:i>a?1:0}),"value")},j.groupBy=function(e,t){var i={},a=j.isFunction(t)?t:function(e){return e[t]};return x(e,function(e,t){var o=a(e,t);(i[o]||(i[o]=[])).push(e)}),i},j.sortedIndex=function(e,t,i){i||(i=j.identity);for(var a=0,o=e.length;o>a;){var s=a+o>>1;i(e[s])<i(t)?a=s+1:o=s}return a},j.toArray=function(e){return e?e.toArray?e.toArray():j.isArray(e)?r.call(e):j.isArguments(e)?r.call(e):j.values(e):[]},j.size=function(e){return j.toArray(e).length},j.first=j.head=function(e,t,i){return null==t||i?e[0]:r.call(e,0,t)},j.initial=function(e,t,i){return r.call(e,0,e.length-(null==t||i?1:t))},j.last=function(e,t,i){return null==t||i?e[e.length-1]:r.call(e,Math.max(e.length-t,0))},j.rest=j.tail=function(e,t,i){return r.call(e,null==t||i?1:t)},j.compact=function(e){return j.filter(e,function(e){return!!e})},j.flatten=function(e,t){return j.reduce(e,function(e,i){return j.isArray(i)?e.concat(t?i:j.flatten(i)):(e[e.length]=i,e)},[])},j.without=function(e){return j.difference(e,r.call(arguments,1))},j.uniq=j.unique=function(e,t,i){var a=i?j.map(e,i):e,o=[];return j.reduce(a,function(i,a,s){return 0!=s&&(t===!0?j.last(i)==a:j.include(i,a))||(i[i.length]=a,o[o.length]=e[s]),i},[]),o},j.union=function(){return j.uniq(j.flatten(arguments,!0))},j.intersection=j.intersect=function(e){var t=r.call(arguments,1);return j.filter(j.uniq(e),function(e){return j.every(t,function(t){return j.indexOf(t,e)>=0})})},j.difference=function(e){var t=j.flatten(r.call(arguments,1));return j.filter(e,function(e){return!j.include(t,e)})},j.zip=function(){for(var e=r.call(arguments),t=j.max(j.pluck(e,"length")),i=Array(t),a=0;t>a;a++)i[a]=j.pluck(e,""+a);return i},j.indexOf=function(e,t,i){if(null==e)return-1;var a,o;if(i)return a=j.sortedIndex(e,t),e[a]===t?a:-1;if(b&&e.indexOf===b)return e.indexOf(t);for(a=0,o=e.length;o>a;a++)if(a in e&&e[a]===t)return a;return-1},j.lastIndexOf=function(e,t){if(null==e)return-1;if(y&&e.lastIndexOf===y)return e.lastIndexOf(t);for(var i=e.length;i--;)if(i in e&&e[i]===t)return i;return-1},j.range=function(e,t,i){1>=arguments.length&&(t=e||0,e=0),i=arguments[2]||1;for(var a=Math.max(Math.ceil((t-e)/i),0),o=0,s=Array(a);a>o;)s[o++]=e,e+=i;return s};var C=function(){};j.bind=function(e,t){var i,a;if(e.bind===_&&_)return _.apply(e,r.call(arguments,1));if(!j.isFunction(e))throw new TypeError;return a=r.call(arguments,2),i=function(){if(!(this instanceof i))return e.apply(t,a.concat(r.call(arguments)));C.prototype=e.prototype;var o=new C,s=e.apply(o,a.concat(r.call(arguments)));return Object(s)===s?s:o}},j.bindAll=function(e){var t=r.call(arguments,1);return 0==t.length&&(t=j.functions(e)),x(t,function(t){e[t]=j.bind(e[t],e)}),e},j.memoize=function(e,t){var i={};return t||(t=j.identity),function(){var a=t.apply(this,arguments);return j.has(i,a)?i[a]:i[a]=e.apply(this,arguments)}},j.delay=function(e,t){var i=r.call(arguments,2);return setTimeout(function(){return e.apply(e,i)},t)},j.defer=function(e){return j.delay.apply(j,[e,1].concat(r.call(arguments,1)))},j.throttle=function(e,t){var i,a,o,s,n,r=j.debounce(function(){n=s=!1},t);return function(){i=this,a=arguments;var l=function(){o=null,n&&e.apply(i,a),r()};o||(o=setTimeout(l,t)),s?n=!0:e.apply(i,a),r(),s=!0}},j.debounce=function(e,t){var i;return function(){var a=this,o=arguments,s=function(){i=null,e.apply(a,o)};clearTimeout(i),i=setTimeout(s,t)}},j.once=function(e){var t,i=!1;return function(){return i?t:(i=!0,t=e.apply(this,arguments))}},j.wrap=function(e,t){return function(){var i=[e].concat(r.call(arguments,0));return t.apply(this,i)}},j.compose=function(){var e=arguments;return function(){for(var t=arguments,i=e.length-1;i>=0;i--)t=[e[i].apply(this,t)];return t[0]}},j.after=function(e,t){return 0>=e?t():function(){return 1>--e?t.apply(this,arguments):void 0}},j.keys=k||function(e){if(e!==Object(e))throw new TypeError("Invalid object");var t=[];for(var i in e)j.has(e,i)&&(t[t.length]=i);return t},j.values=function(e){return j.map(e,j.identity)},j.functions=j.methods=function(e){var t=[];for(var i in e)j.isFunction(e[i])&&t.push(i);return t.sort()},j.extend=function(e){return x(r.call(arguments,1),function(t){for(var i in t)e[i]=t[i]}),e},j.defaults=function(e){return x(r.call(arguments,1),function(t){for(var i in t)null==e[i]&&(e[i]=t[i])}),e},j.clone=function(e){return j.isObject(e)?j.isArray(e)?e.slice():j.extend({},e):e},j.tap=function(e,t){return t(e),e},j.isEqual=function(t,i){return e(t,i,[])},j.isEmpty=function(e){if(j.isArray(e)||j.isString(e))return 0===e.length;for(var t in e)if(j.has(e,t))return!1;return!0},j.isElement=function(e){return!(!e||1!=e.nodeType)},j.isArray=w||function(e){return"[object Array]"==u.call(e)},j.isObject=function(e){return e===Object(e)},j.isArguments=function(e){return"[object Arguments]"==u.call(e)},j.isArguments(arguments)||(j.isArguments=function(e){return!(!e||!j.has(e,"callee"))}),j.isFunction=function(e){return"[object Function]"==u.call(e)},j.isString=function(e){return"[object String]"==u.call(e)},j.isNumber=function(e){return"[object Number]"==u.call(e)},j.isNaN=function(e){return e!==e},j.isBoolean=function(e){return e===!0||e===!1||"[object Boolean]"==u.call(e)},j.isDate=function(e){return"[object Date]"==u.call(e)},j.isRegExp=function(e){return"[object RegExp]"==u.call(e)},j.isNull=function(e){return null===e},j.isUndefined=function(e){return void 0===e},j.has=function(e,t){return c.call(e,t)},j.noConflict=function(){return t._=i,this},j.identity=function(e){return e},j.times=function(e,t,i){for(var a=0;e>a;a++)t.call(i,a)},j.escape=function(e){return(""+e).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;").replace(/\//g,"&#x2F;")},j.mixin=function(e){x(j.functions(e),function(t){D(t,j[t]=e[t])})};var S=0;j.uniqueId=function(e){var t=S++;return e?e+t:t},j.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g};var T=/.^/,I=function(e){return e.replace(/\\\\/g,"\\").replace(/\\'/g,"'")};j.template=function(e,t){var i=j.templateSettings,a="var __p=[],print=function(){__p.push.apply(__p,arguments);};with(obj||{}){__p.push('"+e.replace(/\\/g,"\\\\").replace(/'/g,"\\'").replace(i.escape||T,function(e,t){return"',_.escape("+I(t)+"),'"}).replace(i.interpolate||T,function(e,t){return"',"+I(t)+",'"}).replace(i.evaluate||T,function(e,t){return"');"+I(t).replace(/[\r\n\t]/g," ")+";__p.push('"}).replace(/\r/g,"\\r").replace(/\n/g,"\\n").replace(/\t/g,"\\t")+"');}return __p.join('');",o=Function("obj","_",a);return t?o(t,j):function(e){return o.call(this,e,j)}},j.chain=function(e){return j(e).chain()};var P=function(e){this._wrapped=e};j.prototype=P.prototype;var E=function(e,t){return t?j(e).chain():e},D=function(e,t){P.prototype[e]=function(){var e=r.call(arguments);return l.call(e,this._wrapped),E(t.apply(j,e),this._chain)}};j.mixin(j),x(["pop","push","reverse","shift","sort","splice","unshift"],function(e){var t=o[e];P.prototype[e]=function(){var i=this._wrapped;t.apply(i,arguments);var a=i.length;return"shift"!=e&&"splice"!=e||0!==a||delete i[0],E(i,this._chain)}}),x(["concat","join","slice"],function(e){var t=o[e];P.prototype[e]=function(){return E(t.apply(this._wrapped,arguments),this._chain)}}),P.prototype.chain=function(){return this._chain=!0,this},P.prototype.value=function(){return this._wrapped}}).call(this);
define("underscore", (function (global) {
    return function () {
        var ret, fn;
        return ret || global._;
    };
}(this)));

(function(e,t){function i(e){var t,i,a=R[e]={};for(e=e.split(/\s+/),t=0,i=e.length;i>t;t++)a[e[t]]=!0;return a}function a(e,i,a){if(a===t&&1===e.nodeType){var o="data-"+i.replace(B,"-$1").toLowerCase();if(a=e.getAttribute(o),"string"==typeof a){try{a="true"===a?!0:"false"===a?!1:"null"===a?null:O.isNumeric(a)?parseFloat(a):L.test(a)?O.parseJSON(a):a}catch(n){}O.data(e,i,a)}else a=t}return a}function o(e){for(var t in e)if(("data"!==t||!O.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}function n(e,t,i){var a=t+"defer",o=t+"queue",n=t+"mark",s=O._data(e,a);!s||"queue"!==i&&O._data(e,o)||"mark"!==i&&O._data(e,n)||setTimeout(function(){O._data(e,o)||O._data(e,n)||(O.removeData(e,a,!0),s.fire())},0)}function s(){return!1}function r(){return!0}function l(e){return!e||!e.parentNode||11===e.parentNode.nodeType}function u(e,t,i){if(t=t||0,O.isFunction(t))return O.grep(e,function(e,a){var o=!!t.call(e,a,e);return o===i});if(t.nodeType)return O.grep(e,function(e){return e===t===i});if("string"==typeof t){var a=O.grep(e,function(e){return 1===e.nodeType});if(dt.test(t))return O.filter(t,a,!i);t=O.filter(t,a)}return O.grep(e,function(e){return O.inArray(e,t)>=0===i})}function c(e){var t=mt.split("|"),i=e.createDocumentFragment();if(i.createElement)for(;t.length;)i.createElement(t.pop());return i}function d(e){return O.nodeName(e,"table")?e.getElementsByTagName("tbody")[0]||e.appendChild(e.ownerDocument.createElement("tbody")):e}function p(e,t){if(1===t.nodeType&&O.hasData(e)){var i,a,o,n=O._data(e),s=O._data(t,n),r=n.events;if(r){delete s.handle,s.events={};for(i in r)for(a=0,o=r[i].length;o>a;a++)O.event.add(t,i+(r[i][a].namespace?".":"")+r[i][a].namespace,r[i][a],r[i][a].data)}s.data&&(s.data=O.extend({},s.data))}}function h(e,t){var i;1===t.nodeType&&(t.clearAttributes&&t.clearAttributes(),t.mergeAttributes&&t.mergeAttributes(e),i=t.nodeName.toLowerCase(),"object"===i?t.outerHTML=e.outerHTML:"input"!==i||"checkbox"!==e.type&&"radio"!==e.type?"option"===i?t.selected=e.defaultSelected:("input"===i||"textarea"===i)&&(t.defaultValue=e.defaultValue):(e.checked&&(t.defaultChecked=t.checked=e.checked),t.value!==e.value&&(t.value=e.value)),t.removeAttribute(O.expando))}function f(e){return e.getElementsByTagName!==t?e.getElementsByTagName("*"):e.querySelectorAll!==t?e.querySelectorAll("*"):[]}function m(e){("checkbox"===e.type||"radio"===e.type)&&(e.defaultChecked=e.checked)}function g(e){var i=(e.nodeName||"").toLowerCase();"input"===i?m(e):"script"!==i&&e.getElementsByTagName!==t&&O.grep(e.getElementsByTagName("input"),m)}function v(e){var t=M.createElement("div");return Et.appendChild(t),t.innerHTML=e.outerHTML,t.firstChild}function b(e,t){t.src?O.ajax({url:t.src,async:!1,dataType:"script"}):O.globalEval((t.text||t.textContent||t.innerHTML||"").replace(St,"/*$0*/")),t.parentNode&&t.parentNode.removeChild(t)}function y(e,t,i){var a="width"===t?e.offsetWidth:e.offsetHeight,o="width"===t?Bt:qt,n=0,s=o.length;if(a>0){if("border"!==i)for(;s>n;n++)i||(a-=parseFloat(O.css(e,"padding"+o[n]))||0),"margin"===i?a+=parseFloat(O.css(e,i+o[n]))||0:a-=parseFloat(O.css(e,"border"+o[n]+"Width"))||0;return a+"px"}if(a=It(e,t,t),(0>a||null==a)&&(a=e.style[t]||0),a=parseFloat(a)||0,i)for(;s>n;n++)a+=parseFloat(O.css(e,"padding"+o[n]))||0,"padding"!==i&&(a+=parseFloat(O.css(e,"border"+o[n]+"Width"))||0),"margin"===i&&(a+=parseFloat(O.css(e,i+o[n]))||0);return a+"px"}function w(e){return function(t,i){if("string"!=typeof t&&(i=t,t="*"),O.isFunction(i))for(var a,o,n,s=t.toLowerCase().split(ii),r=0,l=s.length;l>r;r++)a=s[r],n=/^\+/.test(a),n&&(a=a.substr(1)||"*"),o=e[a]=e[a]||[],o[n?"unshift":"push"](i)}}function k(e,i,a,o,n,s){n=n||i.dataTypes[0],s=s||{},s[n]=!0;for(var r,l=e[n],u=0,c=l?l.length:0,d=e===si;c>u&&(d||!r);u++)r=l[u](i,a,o),"string"==typeof r&&(!d||s[r]?r=t:(i.dataTypes.unshift(r),r=k(e,i,a,o,r,s)));return!d&&r||s["*"]||(r=k(e,i,a,o,"*",s)),r}function _(e,i){var a,o,n=O.ajaxSettings.flatOptions||{};for(a in i)i[a]!==t&&((n[a]?e:o||(o={}))[a]=i[a]);o&&O.extend(!0,e,o)}function x(e,t,i,a){if(O.isArray(t))O.each(t,function(t,o){i||Wt.test(e)?a(e,o):x(e+"["+("object"==typeof o||O.isArray(o)?t:"")+"]",o,i,a)});else if(i||null==t||"object"!=typeof t)a(e,t);else for(var o in t)x(e+"["+o+"]",t[o],i,a)}function j(e,i,a){var o,n,s,r,l=e.contents,u=e.dataTypes,c=e.responseFields;for(n in c)n in a&&(i[c[n]]=a[n]);for(;"*"===u[0];)u.shift(),o===t&&(o=e.mimeType||i.getResponseHeader("content-type"));if(o)for(n in l)if(l[n]&&l[n].test(o)){u.unshift(n);break}if(u[0]in a)s=u[0];else{for(n in a){if(!u[0]||e.converters[n+" "+u[0]]){s=n;break}r||(r=n)}s=s||r}return s?(s!==u[0]&&u.unshift(s),a[s]):t}function A(e,i){e.dataFilter&&(i=e.dataFilter(i,e.dataType));var a,o,n,s,r,l,u,c,d=e.dataTypes,p={},h=d.length,f=d[0];for(a=1;h>a;a++){if(1===a)for(o in e.converters)"string"==typeof o&&(p[o.toLowerCase()]=e.converters[o]);if(s=f,f=d[a],"*"===f)f=s;else if("*"!==s&&s!==f){if(r=s+" "+f,l=p[r]||p["* "+f],!l){c=t;for(u in p)if(n=u.split(" "),(n[0]===s||"*"===n[0])&&(c=p[n[1]+" "+f])){u=p[u],u===!0?l=c:c===!0&&(l=u);break}}l||c||O.error("No conversion from "+r.replace(" "," to ")),l!==!0&&(i=l?l(i):c(u(i)))}}return i}function C(){try{return new e.XMLHttpRequest}catch(t){}}function S(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}function T(){return setTimeout(E,0),bi=O.now()}function E(){bi=t}function I(e,t){var i={};return O.each(_i.concat.apply([],_i.slice(0,t)),function(){i[this]=e}),i}function P(e){if(!yi[e]){var t=M.body,i=O("<"+e+">").appendTo(t),a=i.css("display");i.remove(),("none"===a||""===a)&&(mi||(mi=M.createElement("iframe"),mi.frameBorder=mi.width=mi.height=0),t.appendChild(mi),gi&&mi.createElement||(gi=(mi.contentWindow||mi.contentDocument).document,gi.write(("CSS1Compat"===M.compatMode?"<!doctype html>":"")+"<html><body>"),gi.close()),i=gi.createElement(e),gi.body.appendChild(i),a=O.css(i,"display"),t.removeChild(mi)),yi[e]=a}return yi[e]}function D(e){return O.isWindow(e)?e:9===e.nodeType?e.defaultView||e.parentWindow:!1}var M=e.document,N=e.navigator,$=e.location,O=function(){function i(){if(!r.isReady){try{M.documentElement.doScroll("left")}catch(e){return setTimeout(i,1),t}r.ready()}}var a,o,n,s,r=function(e,t){return new r.fn.init(e,t,a)},l=e.jQuery,u=e.$,c=/^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,d=/\S/,p=/^\s+/,h=/\s+$/,f=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,m=/^[\],:{}\s]*$/,g=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,v=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,b=/(?:^|:|,)(?:\s*\[)+/g,y=/(webkit)[ \/]([\w.]+)/,w=/(opera)(?:.*version)?[ \/]([\w.]+)/,k=/(msie) ([\w.]+)/,_=/(mozilla)(?:.*? rv:([\w.]+))?/,x=/-([a-z]|[0-9])/gi,j=/^-ms-/,A=function(e,t){return(t+"").toUpperCase()},C=N.userAgent,S=Object.prototype.toString,T=Object.prototype.hasOwnProperty,E=Array.prototype.push,I=Array.prototype.slice,P=String.prototype.trim,D=Array.prototype.indexOf,$={};return r.fn=r.prototype={constructor:r,init:function(e,i,a){var o,n,s,l;if(!e)return this;if(e.nodeType)return this.context=this[0]=e,this.length=1,this;if("body"===e&&!i&&M.body)return this.context=M,this[0]=M.body,this.selector=e,this.length=1,this;if("string"==typeof e){if(o="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:c.exec(e),!o||!o[1]&&i)return!i||i.jquery?(i||a).find(e):this.constructor(i).find(e);if(o[1])return i=i instanceof r?i[0]:i,l=i?i.ownerDocument||i:M,s=f.exec(e),s?r.isPlainObject(i)?(e=[M.createElement(s[1])],r.fn.attr.call(e,i,!0)):e=[l.createElement(s[1])]:(s=r.buildFragment([o[1]],[l]),e=(s.cacheable?r.clone(s.fragment):s.fragment).childNodes),r.merge(this,e);if(n=M.getElementById(o[2]),n&&n.parentNode){if(n.id!==o[2])return a.find(e);this.length=1,this[0]=n}return this.context=M,this.selector=e,this}return r.isFunction(e)?a.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),r.makeArray(e,this))},selector:"",jquery:"1.7.1",length:0,size:function(){return this.length},toArray:function(){return I.call(this,0)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e,t,i){var a=this.constructor();return r.isArray(e)?E.apply(a,e):r.merge(a,e),a.prevObject=this,a.context=this.context,"find"===t?a.selector=this.selector+(this.selector?" ":"")+i:t&&(a.selector=this.selector+"."+t+"("+i+")"),a},each:function(e,t){return r.each(this,e,t)},ready:function(e){return r.bindReady(),n.add(e),this},eq:function(e){return e=+e,-1===e?this.slice(e):this.slice(e,e+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(I.apply(this,arguments),"slice",I.call(arguments).join(","))},map:function(e){return this.pushStack(r.map(this,function(t,i){return e.call(t,i,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},r.fn.init.prototype=r.fn,r.extend=r.fn.extend=function(){var e,i,a,o,n,s,l=arguments[0]||{},u=1,c=arguments.length,d=!1;for("boolean"==typeof l&&(d=l,l=arguments[1]||{},u=2),"object"==typeof l||r.isFunction(l)||(l={}),c===u&&(l=this,--u);c>u;u++)if(null!=(e=arguments[u]))for(i in e)a=l[i],o=e[i],l!==o&&(d&&o&&(r.isPlainObject(o)||(n=r.isArray(o)))?(n?(n=!1,s=a&&r.isArray(a)?a:[]):s=a&&r.isPlainObject(a)?a:{},l[i]=r.extend(d,s,o)):o!==t&&(l[i]=o));return l},r.extend({noConflict:function(t){return e.$===r&&(e.$=u),t&&e.jQuery===r&&(e.jQuery=l),r},isReady:!1,readyWait:1,holdReady:function(e){e?r.readyWait++:r.ready(!0)},ready:function(e){if(e===!0&&!--r.readyWait||e!==!0&&!r.isReady){if(!M.body)return setTimeout(r.ready,1);if(r.isReady=!0,e!==!0&&--r.readyWait>0)return;n.fireWith(M,[r]),r.fn.trigger&&r(M).trigger("ready").off("ready")}},bindReady:function(){if(!n){if(n=r.Callbacks("once memory"),"complete"===M.readyState)return setTimeout(r.ready,1);if(M.addEventListener)M.addEventListener("DOMContentLoaded",s,!1),e.addEventListener("load",r.ready,!1);else if(M.attachEvent){M.attachEvent("onreadystatechange",s),e.attachEvent("onload",r.ready);var t=!1;try{t=null==e.frameElement}catch(a){}M.documentElement.doScroll&&t&&i()}}},isFunction:function(e){return"function"===r.type(e)},isArray:Array.isArray||function(e){return"array"===r.type(e)},isWindow:function(e){return e&&"object"==typeof e&&"setInterval"in e},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":$[S.call(e)]||"object"},isPlainObject:function(e){if(!e||"object"!==r.type(e)||e.nodeType||r.isWindow(e))return!1;try{if(e.constructor&&!T.call(e,"constructor")&&!T.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(i){return!1}var a;for(a in e);return a===t||T.call(e,a)},isEmptyObject:function(e){for(var t in e)return!1;return!0},error:function(e){throw Error(e)},parseJSON:function(i){return"string"==typeof i&&i?(i=r.trim(i),e.JSON&&e.JSON.parse?e.JSON.parse(i):m.test(i.replace(g,"@").replace(v,"]").replace(b,""))?Function("return "+i)():(r.error("Invalid JSON: "+i),t)):null},parseXML:function(i){var a,o;try{e.DOMParser?(o=new DOMParser,a=o.parseFromString(i,"text/xml")):(a=new ActiveXObject("Microsoft.XMLDOM"),a.async="false",a.loadXML(i))}catch(n){a=t}return a&&a.documentElement&&!a.getElementsByTagName("parsererror").length||r.error("Invalid XML: "+i),a},noop:function(){},globalEval:function(t){t&&d.test(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(j,"ms-").replace(x,A)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toUpperCase()===t.toUpperCase()},each:function(e,i,a){var o,n=0,s=e.length,l=s===t||r.isFunction(e);if(a)if(l){for(o in e)if(i.apply(e[o],a)===!1)break}else for(;s>n&&i.apply(e[n++],a)!==!1;);else if(l){for(o in e)if(i.call(e[o],o,e[o])===!1)break}else for(;s>n&&i.call(e[n],n,e[n++])!==!1;);return e},trim:P?function(e){return null==e?"":P.call(e)}:function(e){return null==e?"":(""+e).replace(p,"").replace(h,"")},makeArray:function(e,t){var i=t||[];if(null!=e){var a=r.type(e);null==e.length||"string"===a||"function"===a||"regexp"===a||r.isWindow(e)?E.call(i,e):r.merge(i,e)}return i},inArray:function(e,t,i){var a;if(t){if(D)return D.call(t,e,i);for(a=t.length,i=i?0>i?Math.max(0,a+i):i:0;a>i;i++)if(i in t&&t[i]===e)return i}return-1},merge:function(e,i){var a=e.length,o=0;if("number"==typeof i.length)for(var n=i.length;n>o;o++)e[a++]=i[o];else for(;i[o]!==t;)e[a++]=i[o++];return e.length=a,e},grep:function(e,t,i){var a,o=[];i=!!i;for(var n=0,s=e.length;s>n;n++)a=!!t(e[n],n),i!==a&&o.push(e[n]);return o},map:function(e,i,a){var o,n,s=[],l=0,u=e.length,c=e instanceof r||u!==t&&"number"==typeof u&&(u>0&&e[0]&&e[u-1]||0===u||r.isArray(e));if(c)for(;u>l;l++)o=i(e[l],l,a),null!=o&&(s[s.length]=o);else for(n in e)o=i(e[n],n,a),null!=o&&(s[s.length]=o);return s.concat.apply([],s)},guid:1,proxy:function(e,i){if("string"==typeof i){var a=e[i];i=e,e=a}if(!r.isFunction(e))return t;var o=I.call(arguments,2),n=function(){return e.apply(i,o.concat(I.call(arguments)))};return n.guid=e.guid=e.guid||n.guid||r.guid++,n},access:function(e,i,a,o,n,s){var l=e.length;if("object"==typeof i){for(var u in i)r.access(e,u,i[u],o,n,a);return e}if(a!==t){o=!s&&o&&r.isFunction(a);for(var c=0;l>c;c++)n(e[c],i,o?a.call(e[c],c,n(e[c],i)):a,s);return e}return l?n(e[0],i):t},now:function(){return(new Date).getTime()},uaMatch:function(e){e=e.toLowerCase();var t=y.exec(e)||w.exec(e)||k.exec(e)||0>e.indexOf("compatible")&&_.exec(e)||[];return{browser:t[1]||"",version:t[2]||"0"}},sub:function(){function e(t,i){return new e.fn.init(t,i)}r.extend(!0,e,this),e.superclass=this,e.fn=e.prototype=this(),e.fn.constructor=e,e.sub=this.sub,e.fn.init=function(i,a){return a&&a instanceof r&&!(a instanceof e)&&(a=e(a)),r.fn.init.call(this,i,a,t)},e.fn.init.prototype=e.fn;var t=e(M);return e},browser:{}}),r.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(e,t){$["[object "+t+"]"]=t.toLowerCase()}),o=r.uaMatch(C),o.browser&&(r.browser[o.browser]=!0,r.browser.version=o.version),r.browser.webkit&&(r.browser.safari=!0),d.test(" ")&&(p=/^[\s\xA0]+/,h=/[\s\xA0]+$/),a=r(M),M.addEventListener?s=function(){M.removeEventListener("DOMContentLoaded",s,!1),r.ready()}:M.attachEvent&&(s=function(){"complete"===M.readyState&&(M.detachEvent("onreadystatechange",s),r.ready())}),r}(),R={};O.Callbacks=function(e){e=e?R[e]||i(e):{};var a,o,n,s,r,l=[],u=[],c=function(t){var i,a,o,n;for(i=0,a=t.length;a>i;i++)o=t[i],n=O.type(o),"array"===n?c(o):"function"===n&&(e.unique&&p.has(o)||l.push(o))},d=function(t,i){for(i=i||[],a=!e.memory||[t,i],o=!0,r=n||0,n=0,s=l.length;l&&s>r;r++)if(l[r].apply(t,i)===!1&&e.stopOnFalse){a=!0;break}o=!1,l&&(e.once?a===!0?p.disable():l=[]:u&&u.length&&(a=u.shift(),p.fireWith(a[0],a[1])))},p={add:function(){if(l){var e=l.length;c(arguments),o?s=l.length:a&&a!==!0&&(n=e,d(a[0],a[1]))}return this},remove:function(){if(l)for(var t=arguments,i=0,a=t.length;a>i;i++)for(var n=0;l.length>n&&(t[i]!==l[n]||(o&&s>=n&&(s--,r>=n&&r--),l.splice(n--,1),!e.unique));n++);return this},has:function(e){if(l)for(var t=0,i=l.length;i>t;t++)if(e===l[t])return!0;return!1},empty:function(){return l=[],this},disable:function(){return l=u=a=t,this},disabled:function(){return!l},lock:function(){return u=t,a&&a!==!0||p.disable(),this},locked:function(){return!u},fireWith:function(t,i){return u&&(o?e.once||u.push([t,i]):e.once&&a||d(t,i)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!a}};return p};var z=[].slice;O.extend({Deferred:function(e){var t,i=O.Callbacks("once memory"),a=O.Callbacks("once memory"),o=O.Callbacks("memory"),n="pending",s={resolve:i,reject:a,notify:o},r={done:i.add,fail:a.add,progress:o.add,state:function(){return n},isResolved:i.fired,isRejected:a.fired,then:function(e,t,i){return l.done(e).fail(t).progress(i),this},always:function(){return l.done.apply(l,arguments).fail.apply(l,arguments),this},pipe:function(e,t,i){return O.Deferred(function(a){O.each({done:[e,"resolve"],fail:[t,"reject"],progress:[i,"notify"]},function(e,t){var i,o=t[0],n=t[1];O.isFunction(o)?l[e](function(){i=o.apply(this,arguments),i&&O.isFunction(i.promise)?i.promise().then(a.resolve,a.reject,a.notify):a[n+"With"](this===l?a:this,[i])}):l[e](a[n])})}).promise()},promise:function(e){if(null==e)e=r;else for(var t in r)e[t]=r[t];return e}},l=r.promise({});for(t in s)l[t]=s[t].fire,l[t+"With"]=s[t].fireWith;return l.done(function(){n="resolved"},a.disable,o.lock).fail(function(){n="rejected"},i.disable,o.lock),e&&e.call(l,l),l},when:function(e){function t(e){return function(t){a[e]=arguments.length>1?z.call(arguments,0):t,--r||l.resolveWith(l,a)}}function i(e){return function(t){s[e]=arguments.length>1?z.call(arguments,0):t,l.notifyWith(u,s)}}var a=z.call(arguments,0),o=0,n=a.length,s=Array(n),r=n,l=1>=n&&e&&O.isFunction(e.promise)?e:O.Deferred(),u=l.promise();if(n>1){for(;n>o;o++)a[o]&&a[o].promise&&O.isFunction(a[o].promise)?a[o].promise().then(t(o),l.reject,i(o)):--r;r||l.resolveWith(l,a)}else l!==e&&l.resolveWith(l,n?[e]:[]);return u}}),O.support=function(){var i,a,o,n,s,r,l,u,c,d,p,h,f=M.createElement("div");if(M.documentElement,f.setAttribute("className","t"),f.innerHTML="   <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",a=f.getElementsByTagName("*"),o=f.getElementsByTagName("a")[0],!a||!a.length||!o)return{};n=M.createElement("select"),s=n.appendChild(M.createElement("option")),r=f.getElementsByTagName("input")[0],i={leadingWhitespace:3===f.firstChild.nodeType,tbody:!f.getElementsByTagName("tbody").length,htmlSerialize:!!f.getElementsByTagName("link").length,style:/top/.test(o.getAttribute("style")),hrefNormalized:"/a"===o.getAttribute("href"),opacity:/^0.55/.test(o.style.opacity),cssFloat:!!o.style.cssFloat,checkOn:"on"===r.value,optSelected:s.selected,getSetAttribute:"t"!==f.className,enctype:!!M.createElement("form").enctype,html5Clone:"<:nav></:nav>"!==M.createElement("nav").cloneNode(!0).outerHTML,submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},r.checked=!0,i.noCloneChecked=r.cloneNode(!0).checked,n.disabled=!0,i.optDisabled=!s.disabled;try{delete f.test}catch(m){i.deleteExpando=!1}if(!f.addEventListener&&f.attachEvent&&f.fireEvent&&(f.attachEvent("onclick",function(){i.noCloneEvent=!1}),f.cloneNode(!0).fireEvent("onclick")),r=M.createElement("input"),r.value="t",r.setAttribute("type","radio"),i.radioValue="t"===r.value,r.setAttribute("checked","checked"),f.appendChild(r),u=M.createDocumentFragment(),u.appendChild(f.lastChild),i.checkClone=u.cloneNode(!0).cloneNode(!0).lastChild.checked,i.appendChecked=r.checked,u.removeChild(r),u.appendChild(f),f.innerHTML="",e.getComputedStyle&&(l=M.createElement("div"),l.style.width="0",l.style.marginRight="0",f.style.width="2px",f.appendChild(l),i.reliableMarginRight=0===(parseInt((e.getComputedStyle(l,null)||{marginRight:0}).marginRight,10)||0)),f.attachEvent)for(p in{submit:1,change:1,focusin:1})d="on"+p,h=d in f,h||(f.setAttribute(d,"return;"),h="function"==typeof f[d]),i[p+"Bubbles"]=h;return u.removeChild(f),u=n=s=l=f=r=null,O(function(){var e,a,o,n,s,r,l,u,d,p,m=M.getElementsByTagName("body")[0];m&&(r=1,l="position:absolute;top:0;left:0;width:1px;height:1px;margin:0;",u="visibility:hidden;border:0;",d="style='"+l+"border:5px solid #000;padding:0;'",p="<div "+d+"><div></div></div>"+"<table "+d+" cellpadding='0' cellspacing='0'>"+"<tr><td></td></tr></table>",e=M.createElement("div"),e.style.cssText=u+"width:0;height:0;position:static;top:0;margin-top:"+r+"px",m.insertBefore(e,m.firstChild),f=M.createElement("div"),e.appendChild(f),f.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>",c=f.getElementsByTagName("td"),h=0===c[0].offsetHeight,c[0].style.display="",c[1].style.display="none",i.reliableHiddenOffsets=h&&0===c[0].offsetHeight,f.innerHTML="",f.style.width=f.style.paddingLeft="1px",O.boxModel=i.boxModel=2===f.offsetWidth,f.style.zoom!==t&&(f.style.display="inline",f.style.zoom=1,i.inlineBlockNeedsLayout=2===f.offsetWidth,f.style.display="",f.innerHTML="<div style='width:4px;'></div>",i.shrinkWrapBlocks=2!==f.offsetWidth),f.style.cssText=l+u,f.innerHTML=p,a=f.firstChild,o=a.firstChild,n=a.nextSibling.firstChild.firstChild,s={doesNotAddBorder:5!==o.offsetTop,doesAddBorderForTableAndCells:5===n.offsetTop},o.style.position="fixed",o.style.top="20px",s.fixedPosition=20===o.offsetTop||15===o.offsetTop,o.style.position=o.style.top="",a.style.overflow="hidden",a.style.position="relative",s.subtractsBorderForOverflowNotVisible=-5===o.offsetTop,s.doesNotIncludeMarginInBodyOffset=m.offsetTop!==r,m.removeChild(e),f=e=null,O.extend(i,s))}),i}();var L=/^(?:\{.*\}|\[.*\])$/,B=/([A-Z])/g;O.extend({cache:{},uuid:0,expando:"jQuery"+(O.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?O.cache[e[O.expando]]:e[O.expando],!!e&&!o(e)},data:function(e,i,a,o){if(O.acceptData(e)){var n,s,r,l=O.expando,u="string"==typeof i,c=e.nodeType,d=c?O.cache:e,p=c?e[l]:e[l]&&l,h="events"===i;if(p&&d[p]&&(h||o||d[p].data)||!u||a!==t)return p||(c?e[l]=p=++O.uuid:p=l),d[p]||(d[p]={},c||(d[p].toJSON=O.noop)),("object"==typeof i||"function"==typeof i)&&(o?d[p]=O.extend(d[p],i):d[p].data=O.extend(d[p].data,i)),n=s=d[p],o||(s.data||(s.data={}),s=s.data),a!==t&&(s[O.camelCase(i)]=a),h&&!s[i]?n.events:(u?(r=s[i],null==r&&(r=s[O.camelCase(i)])):r=s,r)}},removeData:function(e,t,i){if(O.acceptData(e)){var a,n,s,r=O.expando,l=e.nodeType,u=l?O.cache:e,c=l?e[r]:r;if(u[c]){if(t&&(a=i?u[c]:u[c].data)){O.isArray(t)||(t in a?t=[t]:(t=O.camelCase(t),t=t in a?[t]:t.split(" ")));for(n=0,s=t.length;s>n;n++)delete a[t[n]];if(!(i?o:O.isEmptyObject)(a))return}(i||(delete u[c].data,o(u[c])))&&(O.support.deleteExpando||!u.setInterval?delete u[c]:u[c]=null,l&&(O.support.deleteExpando?delete e[r]:e.removeAttribute?e.removeAttribute(r):e[r]=null))}}},_data:function(e,t,i){return O.data(e,t,i,!0)},acceptData:function(e){if(e.nodeName){var t=O.noData[e.nodeName.toLowerCase()];if(t)return!(t===!0||e.getAttribute("classid")!==t)}return!0}}),O.fn.extend({data:function(e,i){var o,n,s,r=null;if(e===t){if(this.length&&(r=O.data(this[0]),1===this[0].nodeType&&!O._data(this[0],"parsedAttrs"))){n=this[0].attributes;for(var l=0,u=n.length;u>l;l++)s=n[l].name,0===s.indexOf("data-")&&(s=O.camelCase(s.substring(5)),a(this[0],s,r[s]));O._data(this[0],"parsedAttrs",!0)}return r}return"object"==typeof e?this.each(function(){O.data(this,e)}):(o=e.split("."),o[1]=o[1]?"."+o[1]:"",i===t?(r=this.triggerHandler("getData"+o[1]+"!",[o[0]]),r===t&&this.length&&(r=O.data(this[0],e),r=a(this[0],e,r)),r===t&&o[1]?this.data(o[0]):r):this.each(function(){var t=O(this),a=[o[0],i];t.triggerHandler("setData"+o[1]+"!",a),O.data(this,e,i),t.triggerHandler("changeData"+o[1]+"!",a)}))},removeData:function(e){return this.each(function(){O.removeData(this,e)})}}),O.extend({_mark:function(e,t){e&&(t=(t||"fx")+"mark",O._data(e,t,(O._data(e,t)||0)+1))},_unmark:function(e,t,i){if(e!==!0&&(i=t,t=e,e=!1),t){i=i||"fx";var a=i+"mark",o=e?0:(O._data(t,a)||1)-1;o?O._data(t,a,o):(O.removeData(t,a,!0),n(t,i,"mark"))}},queue:function(e,i,a){var o;return e?(i=(i||"fx")+"queue",o=O._data(e,i),a&&(!o||O.isArray(a)?o=O._data(e,i,O.makeArray(a)):o.push(a)),o||[]):t},dequeue:function(e,t){t=t||"fx";var i=O.queue(e,t),a=i.shift(),o={};"inprogress"===a&&(a=i.shift()),a&&("fx"===t&&i.unshift("inprogress"),O._data(e,t+".run",o),a.call(e,function(){O.dequeue(e,t)},o)),i.length||(O.removeData(e,t+"queue "+t+".run",!0),n(e,t,"queue"))}}),O.fn.extend({queue:function(e,i){return"string"!=typeof e&&(i=e,e="fx"),i===t?O.queue(this[0],e):this.each(function(){var t=O.queue(this,e,i);"fx"===e&&"inprogress"!==t[0]&&O.dequeue(this,e)})},dequeue:function(e){return this.each(function(){O.dequeue(this,e)})},delay:function(e,t){return e=O.fx?O.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,i){var a=setTimeout(t,e);i.stop=function(){clearTimeout(a)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,i){function a(){--l||n.resolveWith(s,[s])}"string"!=typeof e&&(i=e,e=t),e=e||"fx";for(var o,n=O.Deferred(),s=this,r=s.length,l=1,u=e+"defer",c=e+"queue",d=e+"mark";r--;)(o=O.data(s[r],u,t,!0)||(O.data(s[r],c,t,!0)||O.data(s[r],d,t,!0))&&O.data(s[r],u,O.Callbacks("once memory"),!0))&&(l++,o.add(a));return a(),n.promise()}});var q,F,H,U=/[\n\t\r]/g,W=/\s+/,V=/\r/g,Y=/^(?:button|input)$/i,G=/^(?:button|input|object|select|textarea)$/i,K=/^a(?:rea)?$/i,J=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,Q=O.support.getSetAttribute;O.fn.extend({attr:function(e,t){return O.access(this,e,t,!0,O.attr)},removeAttr:function(e){return this.each(function(){O.removeAttr(this,e)})},prop:function(e,t){return O.access(this,e,t,!0,O.prop)},removeProp:function(e){return e=O.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(i){}})},addClass:function(e){var t,i,a,o,n,s,r;if(O.isFunction(e))return this.each(function(t){O(this).addClass(e.call(this,t,this.className))});if(e&&"string"==typeof e)for(t=e.split(W),i=0,a=this.length;a>i;i++)if(o=this[i],1===o.nodeType)if(o.className||1!==t.length){for(n=" "+o.className+" ",s=0,r=t.length;r>s;s++)~n.indexOf(" "+t[s]+" ")||(n+=t[s]+" ");o.className=O.trim(n)}else o.className=e;return this},removeClass:function(e){var i,a,o,n,s,r,l;if(O.isFunction(e))return this.each(function(t){O(this).removeClass(e.call(this,t,this.className))});if(e&&"string"==typeof e||e===t)for(i=(e||"").split(W),a=0,o=this.length;o>a;a++)if(n=this[a],1===n.nodeType&&n.className)if(e){for(s=(" "+n.className+" ").replace(U," "),r=0,l=i.length;l>r;r++)s=s.replace(" "+i[r]+" "," ");n.className=O.trim(s)}else n.className="";return this},toggleClass:function(e,t){var i=typeof e,a="boolean"==typeof t;return O.isFunction(e)?this.each(function(i){O(this).toggleClass(e.call(this,i,this.className,t),t)}):this.each(function(){if("string"===i)for(var o,n=0,s=O(this),r=t,l=e.split(W);o=l[n++];)r=a?r:!s.hasClass(o),s[r?"addClass":"removeClass"](o);else("undefined"===i||"boolean"===i)&&(this.className&&O._data(this,"__className__",this.className),this.className=this.className||e===!1?"":O._data(this,"__className__")||"")})},hasClass:function(e){for(var t=" "+e+" ",i=0,a=this.length;a>i;i++)if(1===this[i].nodeType&&(" "+this[i].className+" ").replace(U," ").indexOf(t)>-1)return!0;return!1},val:function(e){var i,a,o,n=this[0];{if(arguments.length)return o=O.isFunction(e),this.each(function(a){var n,s=O(this);1===this.nodeType&&(n=o?e.call(this,a,s.val()):e,null==n?n="":"number"==typeof n?n+="":O.isArray(n)&&(n=O.map(n,function(e){return null==e?"":e+""})),i=O.valHooks[this.nodeName.toLowerCase()]||O.valHooks[this.type],i&&"set"in i&&i.set(this,n,"value")!==t||(this.value=n))});if(n)return i=O.valHooks[n.nodeName.toLowerCase()]||O.valHooks[n.type],i&&"get"in i&&(a=i.get(n,"value"))!==t?a:(a=n.value,"string"==typeof a?a.replace(V,""):null==a?"":a)}}}),O.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,i,a,o,n=e.selectedIndex,s=[],r=e.options,l="select-one"===e.type;if(0>n)return null;for(i=l?n:0,a=l?n+1:r.length;a>i;i++)if(o=r[i],!(!o.selected||(O.support.optDisabled?o.disabled:null!==o.getAttribute("disabled"))||o.parentNode.disabled&&O.nodeName(o.parentNode,"optgroup"))){if(t=O(o).val(),l)return t;s.push(t)}return l&&!s.length&&r.length?O(r[n]).val():s},set:function(e,t){var i=O.makeArray(t);return O(e).find("option").each(function(){this.selected=O.inArray(O(this).val(),i)>=0}),i.length||(e.selectedIndex=-1),i}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attr:function(e,i,a,o){var n,s,r,l=e.nodeType;if(e&&3!==l&&8!==l&&2!==l)return o&&i in O.attrFn?O(e)[i](a):e.getAttribute===t?O.prop(e,i,a):(r=1!==l||!O.isXMLDoc(e),r&&(i=i.toLowerCase(),s=O.attrHooks[i]||(J.test(i)?F:q)),a!==t?null===a?(O.removeAttr(e,i),t):s&&"set"in s&&r&&(n=s.set(e,a,i))!==t?n:(e.setAttribute(i,""+a),a):s&&"get"in s&&r&&null!==(n=s.get(e,i))?n:(n=e.getAttribute(i),null===n?t:n))},removeAttr:function(e,t){var i,a,o,n,s=0;if(t&&1===e.nodeType)for(a=t.toLowerCase().split(W),n=a.length;n>s;s++)o=a[s],o&&(i=O.propFix[o]||o,O.attr(e,o,""),e.removeAttribute(Q?o:i),J.test(o)&&i in e&&(e[i]=!1))},attrHooks:{type:{set:function(e,t){if(Y.test(e.nodeName)&&e.parentNode)O.error("type property can't be changed");else if(!O.support.radioValue&&"radio"===t&&O.nodeName(e,"input")){var i=e.value;return e.setAttribute("type",t),i&&(e.value=i),t}}},value:{get:function(e,t){return q&&O.nodeName(e,"button")?q.get(e,t):t in e?e.value:null},set:function(e,i,a){return q&&O.nodeName(e,"button")?q.set(e,i,a):(e.value=i,t)}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(e,i,a){var o,n,s,r=e.nodeType;if(e&&3!==r&&8!==r&&2!==r)return s=1!==r||!O.isXMLDoc(e),s&&(i=O.propFix[i]||i,n=O.propHooks[i]),a!==t?n&&"set"in n&&(o=n.set(e,a,i))!==t?o:e[i]=a:n&&"get"in n&&null!==(o=n.get(e,i))?o:e[i]},propHooks:{tabIndex:{get:function(e){var i=e.getAttributeNode("tabindex");return i&&i.specified?parseInt(i.value,10):G.test(e.nodeName)||K.test(e.nodeName)&&e.href?0:t}}}}),O.attrHooks.tabindex=O.propHooks.tabIndex,F={get:function(e,i){var a,o=O.prop(e,i);return o===!0||"boolean"!=typeof o&&(a=e.getAttributeNode(i))&&a.nodeValue!==!1?i.toLowerCase():t},set:function(e,t,i){var a;return t===!1?O.removeAttr(e,i):(a=O.propFix[i]||i,a in e&&(e[a]=!0),e.setAttribute(i,i.toLowerCase())),i}},Q||(H={name:!0,id:!0},q=O.valHooks.button={get:function(e,i){var a;return a=e.getAttributeNode(i),a&&(H[i]?""!==a.nodeValue:a.specified)?a.nodeValue:t},set:function(e,t,i){var a=e.getAttributeNode(i);return a||(a=M.createAttribute(i),e.setAttributeNode(a)),a.nodeValue=t+""}},O.attrHooks.tabindex.set=q.set,O.each(["width","height"],function(e,i){O.attrHooks[i]=O.extend(O.attrHooks[i],{set:function(e,a){return""===a?(e.setAttribute(i,"auto"),a):t}})}),O.attrHooks.contenteditable={get:q.get,set:function(e,t,i){""===t&&(t="false"),q.set(e,t,i)}}),O.support.hrefNormalized||O.each(["href","src","width","height"],function(e,i){O.attrHooks[i]=O.extend(O.attrHooks[i],{get:function(e){var a=e.getAttribute(i,2);return null===a?t:a}})}),O.support.style||(O.attrHooks.style={get:function(e){return e.style.cssText.toLowerCase()||t},set:function(e,t){return e.style.cssText=""+t}}),O.support.optSelected||(O.propHooks.selected=O.extend(O.propHooks.selected,{get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}})),O.support.enctype||(O.propFix.enctype="encoding"),O.support.checkOn||O.each(["radio","checkbox"],function(){O.valHooks[this]={get:function(e){return null===e.getAttribute("value")?"on":e.value}}}),O.each(["radio","checkbox"],function(){O.valHooks[this]=O.extend(O.valHooks[this],{set:function(e,i){return O.isArray(i)?e.checked=O.inArray(O(e).val(),i)>=0:t}})});var X=/^(?:textarea|input|select)$/i,Z=/^([^\.]*)?(?:\.(.+))?$/,et=/\bhover(\.\S+)?\b/,tt=/^key/,it=/^(?:mouse|contextmenu)|click/,at=/^(?:focusinfocus|focusoutblur)$/,ot=/^(\w*)(?:#([\w\-]+))?(?:\.([\w\-]+))?$/,nt=function(e){var t=ot.exec(e);return t&&(t[1]=(t[1]||"").toLowerCase(),t[3]=t[3]&&RegExp("(?:^|\\s)"+t[3]+"(?:\\s|$)")),t},st=function(e,t){var i=e.attributes||{};return!(t[1]&&e.nodeName.toLowerCase()!==t[1]||t[2]&&(i.id||{}).value!==t[2]||t[3]&&!t[3].test((i["class"]||{}).value))},rt=function(e){return O.event.special.hover?e:e.replace(et,"mouseenter$1 mouseleave$1")};O.event={add:function(e,i,a,o,n){var s,r,l,u,c,d,p,h,f,m,g;if(3!==e.nodeType&&8!==e.nodeType&&i&&a&&(s=O._data(e))){for(a.handler&&(f=a,a=f.handler),a.guid||(a.guid=O.guid++),l=s.events,l||(s.events=l={}),r=s.handle,r||(s.handle=r=function(e){return O===t||e&&O.event.triggered===e.type?t:O.event.dispatch.apply(r.elem,arguments)
},r.elem=e),i=O.trim(rt(i)).split(" "),u=0;i.length>u;u++)c=Z.exec(i[u])||[],d=c[1],p=(c[2]||"").split(".").sort(),g=O.event.special[d]||{},d=(n?g.delegateType:g.bindType)||d,g=O.event.special[d]||{},h=O.extend({type:d,origType:c[1],data:o,handler:a,guid:a.guid,selector:n,quick:nt(n),namespace:p.join(".")},f),m=l[d],m||(m=l[d]=[],m.delegateCount=0,g.setup&&g.setup.call(e,o,p,r)!==!1||(e.addEventListener?e.addEventListener(d,r,!1):e.attachEvent&&e.attachEvent("on"+d,r))),g.add&&(g.add.call(e,h),h.handler.guid||(h.handler.guid=a.guid)),n?m.splice(m.delegateCount++,0,h):m.push(h),O.event.global[d]=!0;e=null}},global:{},remove:function(e,t,i,a,o){var n,s,r,l,u,c,d,p,h,f,m,g,v=O.hasData(e)&&O._data(e);if(v&&(p=v.events)){for(t=O.trim(rt(t||"")).split(" "),n=0;t.length>n;n++)if(s=Z.exec(t[n])||[],r=l=s[1],u=s[2],r){for(h=O.event.special[r]||{},r=(a?h.delegateType:h.bindType)||r,m=p[r]||[],c=m.length,u=u?RegExp("(^|\\.)"+u.split(".").sort().join("\\.(?:.*\\.)?")+"(\\.|$)"):null,d=0;m.length>d;d++)g=m[d],!o&&l!==g.origType||i&&i.guid!==g.guid||u&&!u.test(g.namespace)||a&&a!==g.selector&&("**"!==a||!g.selector)||(m.splice(d--,1),g.selector&&m.delegateCount--,h.remove&&h.remove.call(e,g));0===m.length&&c!==m.length&&(h.teardown&&h.teardown.call(e,u)!==!1||O.removeEvent(e,r,v.handle),delete p[r])}else for(r in p)O.event.remove(e,r+t[n],i,a,!0);O.isEmptyObject(p)&&(f=v.handle,f&&(f.elem=null),O.removeData(e,["events","handle"],!0))}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(i,a,o,n){if(!o||3!==o.nodeType&&8!==o.nodeType){var s,r,l,u,c,d,p,h,f,m,g=i.type||i,v=[];if(!at.test(g+O.event.triggered)&&(g.indexOf("!")>=0&&(g=g.slice(0,-1),r=!0),g.indexOf(".")>=0&&(v=g.split("."),g=v.shift(),v.sort()),o&&!O.event.customEvent[g]||O.event.global[g]))if(i="object"==typeof i?i[O.expando]?i:new O.Event(g,i):new O.Event(g),i.type=g,i.isTrigger=!0,i.exclusive=r,i.namespace=v.join("."),i.namespace_re=i.namespace?RegExp("(^|\\.)"+v.join("\\.(?:.*\\.)?")+"(\\.|$)"):null,d=0>g.indexOf(":")?"on"+g:"",o){if(i.result=t,i.target||(i.target=o),a=null!=a?O.makeArray(a):[],a.unshift(i),p=O.event.special[g]||{},!p.trigger||p.trigger.apply(o,a)!==!1){if(f=[[o,p.bindType||g]],!n&&!p.noBubble&&!O.isWindow(o)){for(m=p.delegateType||g,u=at.test(m+g)?o:o.parentNode,c=null;u;u=u.parentNode)f.push([u,m]),c=u;c&&c===o.ownerDocument&&f.push([c.defaultView||c.parentWindow||e,m])}for(l=0;f.length>l&&!i.isPropagationStopped();l++)u=f[l][0],i.type=f[l][1],h=(O._data(u,"events")||{})[i.type]&&O._data(u,"handle"),h&&h.apply(u,a),h=d&&u[d],h&&O.acceptData(u)&&h.apply(u,a)===!1&&i.preventDefault();return i.type=g,n||i.isDefaultPrevented()||p._default&&p._default.apply(o.ownerDocument,a)!==!1||"click"===g&&O.nodeName(o,"a")||!O.acceptData(o)||d&&o[g]&&("focus"!==g&&"blur"!==g||0!==i.target.offsetWidth)&&!O.isWindow(o)&&(c=o[d],c&&(o[d]=null),O.event.triggered=g,o[g](),O.event.triggered=t,c&&(o[d]=c)),i.result}}else{s=O.cache;for(l in s)s[l].events&&s[l].events[g]&&O.event.trigger(i,a,s[l].handle.elem,!0)}}},dispatch:function(i){i=O.event.fix(i||e.event);var a,o,n,s,r,l,u,c,d,p,h=(O._data(this,"events")||{})[i.type]||[],f=h.delegateCount,m=[].slice.call(arguments,0),g=!i.exclusive&&!i.namespace,v=[];if(m[0]=i,i.delegateTarget=this,f&&!i.target.disabled&&(!i.button||"click"!==i.type))for(s=O(this),s.context=this.ownerDocument||this,n=i.target;n!=this;n=n.parentNode||this){for(l={},c=[],s[0]=n,a=0;f>a;a++)d=h[a],p=d.selector,l[p]===t&&(l[p]=d.quick?st(n,d.quick):s.is(p)),l[p]&&c.push(d);c.length&&v.push({elem:n,matches:c})}for(h.length>f&&v.push({elem:this,matches:h.slice(f)}),a=0;v.length>a&&!i.isPropagationStopped();a++)for(u=v[a],i.currentTarget=u.elem,o=0;u.matches.length>o&&!i.isImmediatePropagationStopped();o++)d=u.matches[o],(g||!i.namespace&&!d.namespace||i.namespace_re&&i.namespace_re.test(d.namespace))&&(i.data=d.data,i.handleObj=d,r=((O.event.special[d.origType]||{}).handle||d.handler).apply(u.elem,m),r!==t&&(i.result=r,r===!1&&(i.preventDefault(),i.stopPropagation())));return i.result},props:"attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,i){var a,o,n,s=i.button,r=i.fromElement;return null==e.pageX&&null!=i.clientX&&(a=e.target.ownerDocument||M,o=a.documentElement,n=a.body,e.pageX=i.clientX+(o&&o.scrollLeft||n&&n.scrollLeft||0)-(o&&o.clientLeft||n&&n.clientLeft||0),e.pageY=i.clientY+(o&&o.scrollTop||n&&n.scrollTop||0)-(o&&o.clientTop||n&&n.clientTop||0)),!e.relatedTarget&&r&&(e.relatedTarget=r===e.target?i.toElement:r),e.which||s===t||(e.which=1&s?1:2&s?3:4&s?2:0),e}},fix:function(e){if(e[O.expando])return e;var i,a,o=e,n=O.event.fixHooks[e.type]||{},s=n.props?this.props.concat(n.props):this.props;for(e=O.Event(o),i=s.length;i;)a=s[--i],e[a]=o[a];return e.target||(e.target=o.srcElement||M),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey===t&&(e.metaKey=e.ctrlKey),n.filter?n.filter(e,o):e},special:{ready:{setup:O.bindReady},load:{noBubble:!0},focus:{delegateType:"focusin"},blur:{delegateType:"focusout"},beforeunload:{setup:function(e,t,i){O.isWindow(this)&&(this.onbeforeunload=i)},teardown:function(e,t){this.onbeforeunload===t&&(this.onbeforeunload=null)}}},simulate:function(e,t,i,a){var o=O.extend(new O.Event,i,{type:e,isSimulated:!0,originalEvent:{}});a?O.event.trigger(o,null,t):O.event.dispatch.call(t,o),o.isDefaultPrevented()&&i.preventDefault()}},O.event.handle=O.event.dispatch,O.removeEvent=M.removeEventListener?function(e,t,i){e.removeEventListener&&e.removeEventListener(t,i,!1)}:function(e,t,i){e.detachEvent&&e.detachEvent("on"+t,i)},O.Event=function(e,i){return this instanceof O.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?r:s):this.type=e,i&&O.extend(this,i),this.timeStamp=e&&e.timeStamp||O.now(),this[O.expando]=!0,t):new O.Event(e,i)},O.Event.prototype={preventDefault:function(){this.isDefaultPrevented=r;var e=this.originalEvent;e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=r;var e=this.originalEvent;e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=r,this.stopPropagation()},isDefaultPrevented:s,isPropagationStopped:s,isImmediatePropagationStopped:s},O.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){O.event.special[e]={delegateType:t,bindType:t,handle:function(e){var i,a=this,o=e.relatedTarget,n=e.handleObj;return n.selector,(!o||o!==a&&!O.contains(a,o))&&(e.type=n.origType,i=n.handler.apply(this,arguments),e.type=t),i}}}),O.support.submitBubbles||(O.event.special.submit={setup:function(){return O.nodeName(this,"form")?!1:(O.event.add(this,"click._submit keypress._submit",function(e){var i=e.target,a=O.nodeName(i,"input")||O.nodeName(i,"button")?i.form:t;a&&!a._submit_attached&&(O.event.add(a,"submit._submit",function(e){this.parentNode&&!e.isTrigger&&O.event.simulate("submit",this.parentNode,e,!0)}),a._submit_attached=!0)}),t)},teardown:function(){return O.nodeName(this,"form")?!1:(O.event.remove(this,"._submit"),t)}}),O.support.changeBubbles||(O.event.special.change={setup:function(){return X.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(O.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),O.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1,O.event.simulate("change",this,e,!0))})),!1):(O.event.add(this,"beforeactivate._change",function(e){var t=e.target;X.test(t.nodeName)&&!t._change_attached&&(O.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||O.event.simulate("change",this.parentNode,e,!0)}),t._change_attached=!0)}),t)},handle:function(e){var i=e.target;return this!==i||e.isSimulated||e.isTrigger||"radio"!==i.type&&"checkbox"!==i.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return O.event.remove(this,"._change"),X.test(this.nodeName)}}),O.support.focusinBubbles||O.each({focus:"focusin",blur:"focusout"},function(e,t){var i=0,a=function(e){O.event.simulate(t,e.target,O.event.fix(e),!0)};O.event.special[t]={setup:function(){0===i++&&M.addEventListener(e,a,!0)},teardown:function(){0===--i&&M.removeEventListener(e,a,!0)}}}),O.fn.extend({on:function(e,i,a,o,n){var r,l;if("object"==typeof e){"string"!=typeof i&&(a=i,i=t);for(l in e)this.on(l,i,a,e[l],n);return this}if(null==a&&null==o?(o=i,a=i=t):null==o&&("string"==typeof i?(o=a,a=t):(o=a,a=i,i=t)),o===!1)o=s;else if(!o)return this;return 1===n&&(r=o,o=function(e){return O().off(e),r.apply(this,arguments)},o.guid=r.guid||(r.guid=O.guid++)),this.each(function(){O.event.add(this,e,o,a,i)})},one:function(e,t,i,a){return this.on.call(this,e,t,i,a,1)},off:function(e,i,a){if(e&&e.preventDefault&&e.handleObj){var o=e.handleObj;return O(e.delegateTarget).off(o.namespace?o.type+"."+o.namespace:o.type,o.selector,o.handler),this}if("object"==typeof e){for(var n in e)this.off(n,i,e[n]);return this}return(i===!1||"function"==typeof i)&&(a=i,i=t),a===!1&&(a=s),this.each(function(){O.event.remove(this,e,a,i)})},bind:function(e,t,i){return this.on(e,null,t,i)},unbind:function(e,t){return this.off(e,null,t)},live:function(e,t,i){return O(this.context).on(e,this.selector,t,i),this},die:function(e,t){return O(this.context).off(e,this.selector||"**",t),this},delegate:function(e,t,i,a){return this.on(t,e,i,a)},undelegate:function(e,t,i){return 1==arguments.length?this.off(e,"**"):this.off(t,e,i)},trigger:function(e,t){return this.each(function(){O.event.trigger(e,t,this)})},triggerHandler:function(e,i){return this[0]?O.event.trigger(e,i,this[0],!0):t},toggle:function(e){var t=arguments,i=e.guid||O.guid++,a=0,o=function(i){var o=(O._data(this,"lastToggle"+e.guid)||0)%a;return O._data(this,"lastToggle"+e.guid,o+1),i.preventDefault(),t[o].apply(this,arguments)||!1};for(o.guid=i;t.length>a;)t[a++].guid=i;return this.click(o)},hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),O.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(e,t){O.fn[t]=function(e,i){return null==i&&(i=e,e=null),arguments.length>0?this.on(t,null,e,i):this.trigger(t)},O.attrFn&&(O.attrFn[t]=!0),tt.test(t)&&(O.event.fixHooks[t]=O.event.keyHooks),it.test(t)&&(O.event.fixHooks[t]=O.event.mouseHooks)}),function(){function e(e,t,i,a,n,s){for(var r=0,l=a.length;l>r;r++){var u=a[r];if(u){var c=!1;for(u=u[e];u;){if(u[o]===i){c=a[u.sizset];break}if(1!==u.nodeType||s||(u[o]=i,u.sizset=r),u.nodeName.toLowerCase()===t){c=u;break}u=u[e]}a[r]=c}}}function i(e,t,i,a,n,s){for(var r=0,l=a.length;l>r;r++){var u=a[r];if(u){var c=!1;for(u=u[e];u;){if(u[o]===i){c=a[u.sizset];break}if(1===u.nodeType)if(s||(u[o]=i,u.sizset=r),"string"!=typeof t){if(u===t){c=!0;break}}else if(p.filter(t,[u]).length>0){c=u;break}u=u[e]}a[r]=c}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,o="sizcache"+(Math.random()+"").replace(".",""),n=0,s=Object.prototype.toString,r=!1,l=!0,u=/\\/g,c=/\r\n/g,d=/\W/;[0,0].sort(function(){return l=!1,0});var p=function(e,t,i,o){i=i||[],t=t||M;var n=t;if(1!==t.nodeType&&9!==t.nodeType)return[];if(!e||"string"!=typeof e)return i;var r,l,u,c,d,h,g,v,y=!0,w=p.isXML(t),k=[],x=e;do if(a.exec(""),r=a.exec(x),r&&(x=r[3],k.push(r[1]),r[2])){c=r[3];break}while(r);if(k.length>1&&m.exec(e))if(2===k.length&&f.relative[k[0]])l=_(k[0]+k[1],t,o);else for(l=f.relative[k[0]]?[t]:p(k.shift(),t);k.length;)e=k.shift(),f.relative[e]&&(e+=k.shift()),l=_(e,l,o);else if(!o&&k.length>1&&9===t.nodeType&&!w&&f.match.ID.test(k[0])&&!f.match.ID.test(k[k.length-1])&&(d=p.find(k.shift(),t,w),t=d.expr?p.filter(d.expr,d.set)[0]:d.set[0]),t)for(d=o?{expr:k.pop(),set:b(o)}:p.find(k.pop(),1!==k.length||"~"!==k[0]&&"+"!==k[0]||!t.parentNode?t:t.parentNode,w),l=d.expr?p.filter(d.expr,d.set):d.set,k.length>0?u=b(l):y=!1;k.length;)h=k.pop(),g=h,f.relative[h]?g=k.pop():h="",null==g&&(g=t),f.relative[h](u,g,w);else u=k=[];if(u||(u=l),u||p.error(h||e),"[object Array]"===s.call(u))if(y)if(t&&1===t.nodeType)for(v=0;null!=u[v];v++)u[v]&&(u[v]===!0||1===u[v].nodeType&&p.contains(t,u[v]))&&i.push(l[v]);else for(v=0;null!=u[v];v++)u[v]&&1===u[v].nodeType&&i.push(l[v]);else i.push.apply(i,u);else b(u,i);return c&&(p(c,n,i,o),p.uniqueSort(i)),i};p.uniqueSort=function(e){if(w&&(r=l,e.sort(w),r))for(var t=1;e.length>t;t++)e[t]===e[t-1]&&e.splice(t--,1);return e},p.matches=function(e,t){return p(e,null,null,t)},p.matchesSelector=function(e,t){return p(t,null,null,[e]).length>0},p.find=function(e,i,a){var o,n,s,r,l,c;if(!e)return[];for(n=0,s=f.order.length;s>n;n++)if(l=f.order[n],(r=f.leftMatch[l].exec(e))&&(c=r[1],r.splice(1,1),"\\"!==c.substr(c.length-1)&&(r[1]=(r[1]||"").replace(u,""),o=f.find[l](r,i,a),null!=o))){e=e.replace(f.match[l],"");break}return o||(o=i.getElementsByTagName!==t?i.getElementsByTagName("*"):[]),{set:o,expr:e}},p.filter=function(e,i,a,o){for(var n,s,r,l,u,c,d,h,m,g=e,v=[],b=i,y=i&&i[0]&&p.isXML(i[0]);e&&i.length;){for(r in f.filter)if(null!=(n=f.leftMatch[r].exec(e))&&n[2]){if(c=f.filter[r],d=n[1],s=!1,n.splice(1,1),"\\"===d.substr(d.length-1))continue;if(b===v&&(v=[]),f.preFilter[r])if(n=f.preFilter[r](n,b,a,v,o,y)){if(n===!0)continue}else s=l=!0;if(n)for(h=0;null!=(u=b[h]);h++)u&&(l=c(u,n,h,b),m=o^l,a&&null!=l?m?s=!0:b[h]=!1:m&&(v.push(u),s=!0));if(l!==t){if(a||(b=v),e=e.replace(f.match[r],""),!s)return[];break}}if(e===g){if(null!=s)break;p.error(e)}g=e}return b},p.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)};var h=p.getText=function(e){var t,i,a=e.nodeType,o="";if(a){if(1===a||9===a){if("string"==typeof e.textContent)return e.textContent;if("string"==typeof e.innerText)return e.innerText.replace(c,"");for(e=e.firstChild;e;e=e.nextSibling)o+=h(e)}else if(3===a||4===a)return e.nodeValue}else for(t=0;i=e[t];t++)8!==i.nodeType&&(o+=h(i));return o},f=p.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(e){return e.getAttribute("href")},type:function(e){return e.getAttribute("type")}},relative:{"+":function(e,t){var i="string"==typeof t,a=i&&!d.test(t),o=i&&!a;a&&(t=t.toLowerCase());for(var n,s=0,r=e.length;r>s;s++)if(n=e[s]){for(;(n=n.previousSibling)&&1!==n.nodeType;);e[s]=o||n&&n.nodeName.toLowerCase()===t?n||!1:n===t}o&&p.filter(t,e,!0)},">":function(e,t){var i,a="string"==typeof t,o=0,n=e.length;if(a&&!d.test(t)){for(t=t.toLowerCase();n>o;o++)if(i=e[o]){var s=i.parentNode;e[o]=s.nodeName.toLowerCase()===t?s:!1}}else{for(;n>o;o++)i=e[o],i&&(e[o]=a?i.parentNode:i.parentNode===t);a&&p.filter(t,e,!0)}},"":function(t,a,o){var s,r=n++,l=i;"string"!=typeof a||d.test(a)||(a=a.toLowerCase(),s=a,l=e),l("parentNode",a,r,t,s,o)},"~":function(t,a,o){var s,r=n++,l=i;"string"!=typeof a||d.test(a)||(a=a.toLowerCase(),s=a,l=e),l("previousSibling",a,r,t,s,o)}},find:{ID:function(e,i,a){if(i.getElementById!==t&&!a){var o=i.getElementById(e[1]);return o&&o.parentNode?[o]:[]}},NAME:function(e,i){if(i.getElementsByName!==t){for(var a=[],o=i.getElementsByName(e[1]),n=0,s=o.length;s>n;n++)o[n].getAttribute("name")===e[1]&&a.push(o[n]);return 0===a.length?null:a}},TAG:function(e,i){return i.getElementsByTagName!==t?i.getElementsByTagName(e[1]):t}},preFilter:{CLASS:function(e,t,i,a,o,n){if(e=" "+e[1].replace(u,"")+" ",n)return e;for(var s,r=0;null!=(s=t[r]);r++)s&&(o^(s.className&&(" "+s.className+" ").replace(/[\t\n\r]/g," ").indexOf(e)>=0)?i||a.push(s):i&&(t[r]=!1));return!1},ID:function(e){return e[1].replace(u,"")},TAG:function(e){return e[1].replace(u,"").toLowerCase()},CHILD:function(e){if("nth"===e[1]){e[2]||p.error(e[0]),e[2]=e[2].replace(/^\+|\s*/g,"");var t=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec("even"===e[2]&&"2n"||"odd"===e[2]&&"2n+1"||!/\D/.test(e[2])&&"0n+"+e[2]||e[2]);e[2]=t[1]+(t[2]||1)-0,e[3]=t[3]-0}else e[2]&&p.error(e[0]);return e[0]=n++,e},ATTR:function(e,t,i,a,o,n){var s=e[1]=e[1].replace(u,"");return!n&&f.attrMap[s]&&(e[1]=f.attrMap[s]),e[4]=(e[4]||e[5]||"").replace(u,""),"~="===e[2]&&(e[4]=" "+e[4]+" "),e},PSEUDO:function(e,t,i,o,n){if("not"===e[1]){if(!((a.exec(e[3])||"").length>1||/^\w/.test(e[3]))){var s=p.filter(e[3],t,i,!0^n);return i||o.push.apply(o,s),!1}e[3]=p(e[3],null,null,t)}else if(f.match.POS.test(e[0])||f.match.CHILD.test(e[0]))return!0;return e},POS:function(e){return e.unshift(!0),e}},filters:{enabled:function(e){return e.disabled===!1&&"hidden"!==e.type},disabled:function(e){return e.disabled===!0},checked:function(e){return e.checked===!0},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},parent:function(e){return!!e.firstChild},empty:function(e){return!e.firstChild},has:function(e,t,i){return!!p(i[3],e).length},header:function(e){return/h\d/i.test(e.nodeName)},text:function(e){var t=e.getAttribute("type"),i=e.type;return"input"===e.nodeName.toLowerCase()&&"text"===i&&(t===i||null===t)},radio:function(e){return"input"===e.nodeName.toLowerCase()&&"radio"===e.type},checkbox:function(e){return"input"===e.nodeName.toLowerCase()&&"checkbox"===e.type},file:function(e){return"input"===e.nodeName.toLowerCase()&&"file"===e.type},password:function(e){return"input"===e.nodeName.toLowerCase()&&"password"===e.type},submit:function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&"submit"===e.type},image:function(e){return"input"===e.nodeName.toLowerCase()&&"image"===e.type},reset:function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&"reset"===e.type},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},input:function(e){return/input|select|textarea|button/i.test(e.nodeName)},focus:function(e){return e===e.ownerDocument.activeElement}},setFilters:{first:function(e,t){return 0===t},last:function(e,t,i,a){return t===a.length-1},even:function(e,t){return 0===t%2},odd:function(e,t){return 1===t%2},lt:function(e,t,i){return i[3]-0>t},gt:function(e,t,i){return t>i[3]-0},nth:function(e,t,i){return i[3]-0===t},eq:function(e,t,i){return i[3]-0===t}},filter:{PSEUDO:function(e,t,i,a){var o=t[1],n=f.filters[o];if(n)return n(e,i,t,a);if("contains"===o)return(e.textContent||e.innerText||h([e])||"").indexOf(t[3])>=0;if("not"===o){for(var s=t[3],r=0,l=s.length;l>r;r++)if(s[r]===e)return!1;return!0}p.error(o)},CHILD:function(e,t){var i,a,n,s,r,l,u=t[1],c=e;switch(u){case"only":case"first":for(;c=c.previousSibling;)if(1===c.nodeType)return!1;if("first"===u)return!0;c=e;case"last":for(;c=c.nextSibling;)if(1===c.nodeType)return!1;return!0;case"nth":if(i=t[2],a=t[3],1===i&&0===a)return!0;if(n=t[0],s=e.parentNode,s&&(s[o]!==n||!e.nodeIndex)){for(r=0,c=s.firstChild;c;c=c.nextSibling)1===c.nodeType&&(c.nodeIndex=++r);s[o]=n}return l=e.nodeIndex-a,0===i?0===l:0===l%i&&l/i>=0}},ID:function(e,t){return 1===e.nodeType&&e.getAttribute("id")===t},TAG:function(e,t){return"*"===t&&1===e.nodeType||!!e.nodeName&&e.nodeName.toLowerCase()===t},CLASS:function(e,t){return(" "+(e.className||e.getAttribute("class"))+" ").indexOf(t)>-1},ATTR:function(e,t){var i=t[1],a=p.attr?p.attr(e,i):f.attrHandle[i]?f.attrHandle[i](e):null!=e[i]?e[i]:e.getAttribute(i),o=a+"",n=t[2],s=t[4];return null==a?"!="===n:!n&&p.attr?null!=a:"="===n?o===s:"*="===n?o.indexOf(s)>=0:"~="===n?(" "+o+" ").indexOf(s)>=0:s?"!="===n?o!==s:"^="===n?0===o.indexOf(s):"$="===n?o.substr(o.length-s.length)===s:"|="===n?o===s||o.substr(0,s.length+1)===s+"-":!1:o&&a!==!1},POS:function(e,i,a,o){var n=i[2],s=f.setFilters[n];return s?s(e,a,i,o):t}}},m=f.match.POS,g=function(e,t){return"\\"+(t-0+1)};for(var v in f.match)f.match[v]=RegExp(f.match[v].source+/(?![^\[]*\])(?![^\(]*\))/.source),f.leftMatch[v]=RegExp(/(^(?:.|\r|\n)*?)/.source+f.match[v].source.replace(/\\(\d+)/g,g));var b=function(e,t){return e=Array.prototype.slice.call(e,0),t?(t.push.apply(t,e),t):e};try{Array.prototype.slice.call(M.documentElement.childNodes,0)[0].nodeType}catch(y){b=function(e,t){var i=0,a=t||[];if("[object Array]"===s.call(e))Array.prototype.push.apply(a,e);else if("number"==typeof e.length)for(var o=e.length;o>i;i++)a.push(e[i]);else for(;e[i];i++)a.push(e[i]);return a}}var w,k;M.documentElement.compareDocumentPosition?w=function(e,t){return e===t?(r=!0,0):e.compareDocumentPosition&&t.compareDocumentPosition?4&e.compareDocumentPosition(t)?-1:1:e.compareDocumentPosition?-1:1}:(w=function(e,t){if(e===t)return r=!0,0;if(e.sourceIndex&&t.sourceIndex)return e.sourceIndex-t.sourceIndex;var i,a,o=[],n=[],s=e.parentNode,l=t.parentNode,u=s;if(s===l)return k(e,t);if(!s)return-1;if(!l)return 1;for(;u;)o.unshift(u),u=u.parentNode;for(u=l;u;)n.unshift(u),u=u.parentNode;i=o.length,a=n.length;for(var c=0;i>c&&a>c;c++)if(o[c]!==n[c])return k(o[c],n[c]);return c===i?k(e,n[c],-1):k(o[c],t,1)},k=function(e,t,i){if(e===t)return i;for(var a=e.nextSibling;a;){if(a===t)return-1;a=a.nextSibling}return 1}),function(){var e=M.createElement("div"),i="script"+(new Date).getTime(),a=M.documentElement;e.innerHTML="<a name='"+i+"'/>",a.insertBefore(e,a.firstChild),M.getElementById(i)&&(f.find.ID=function(e,i,a){if(i.getElementById!==t&&!a){var o=i.getElementById(e[1]);return o?o.id===e[1]||o.getAttributeNode!==t&&o.getAttributeNode("id").nodeValue===e[1]?[o]:t:[]}},f.filter.ID=function(e,i){var a=e.getAttributeNode!==t&&e.getAttributeNode("id");return 1===e.nodeType&&a&&a.nodeValue===i}),a.removeChild(e),a=e=null}(),function(){var e=M.createElement("div");e.appendChild(M.createComment("")),e.getElementsByTagName("*").length>0&&(f.find.TAG=function(e,t){var i=t.getElementsByTagName(e[1]);if("*"===e[1]){for(var a=[],o=0;i[o];o++)1===i[o].nodeType&&a.push(i[o]);i=a}return i}),e.innerHTML="<a href='#'></a>",e.firstChild&&e.firstChild.getAttribute!==t&&"#"!==e.firstChild.getAttribute("href")&&(f.attrHandle.href=function(e){return e.getAttribute("href",2)}),e=null}(),M.querySelectorAll&&function(){var e=p,t=M.createElement("div"),i="__sizzle__";if(t.innerHTML="<p class='TEST'></p>",!t.querySelectorAll||0!==t.querySelectorAll(".TEST").length){p=function(t,a,o,n){if(a=a||M,!n&&!p.isXML(a)){var s=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(t);if(s&&(1===a.nodeType||9===a.nodeType)){if(s[1])return b(a.getElementsByTagName(t),o);if(s[2]&&f.find.CLASS&&a.getElementsByClassName)return b(a.getElementsByClassName(s[2]),o)}if(9===a.nodeType){if("body"===t&&a.body)return b([a.body],o);if(s&&s[3]){var r=a.getElementById(s[3]);if(!r||!r.parentNode)return b([],o);if(r.id===s[3])return b([r],o)}try{return b(a.querySelectorAll(t),o)}catch(l){}}else if(1===a.nodeType&&"object"!==a.nodeName.toLowerCase()){var u=a,c=a.getAttribute("id"),d=c||i,h=a.parentNode,m=/^\s*[+~]/.test(t);c?d=d.replace(/'/g,"\\$&"):a.setAttribute("id",d),m&&h&&(a=a.parentNode);try{if(!m||h)return b(a.querySelectorAll("[id='"+d+"'] "+t),o)}catch(g){}finally{c||u.removeAttribute("id")}}}return e(t,a,o,n)};for(var a in e)p[a]=e[a];t=null}}(),function(){var e=M.documentElement,t=e.matchesSelector||e.mozMatchesSelector||e.webkitMatchesSelector||e.msMatchesSelector;if(t){var i=!t.call(M.createElement("div"),"div"),a=!1;try{t.call(M.documentElement,"[test!='']:sizzle")}catch(o){a=!0}p.matchesSelector=function(e,o){if(o=o.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']"),!p.isXML(e))try{if(a||!f.match.PSEUDO.test(o)&&!/!=/.test(o)){var n=t.call(e,o);if(n||!i||e.document&&11!==e.document.nodeType)return n}}catch(s){}return p(o,null,null,[e]).length>0}}}(),function(){var e=M.createElement("div");e.innerHTML="<div class='test e'></div><div class='test'></div>",e.getElementsByClassName&&0!==e.getElementsByClassName("e").length&&(e.lastChild.className="e",1!==e.getElementsByClassName("e").length&&(f.order.splice(1,0,"CLASS"),f.find.CLASS=function(e,i,a){return i.getElementsByClassName===t||a?t:i.getElementsByClassName(e[1])},e=null))}(),p.contains=M.documentElement.contains?function(e,t){return e!==t&&(e.contains?e.contains(t):!0)}:M.documentElement.compareDocumentPosition?function(e,t){return!!(16&e.compareDocumentPosition(t))}:function(){return!1},p.isXML=function(e){var t=(e?e.ownerDocument||e:0).documentElement;return t?"HTML"!==t.nodeName:!1};var _=function(e,t,i){for(var a,o=[],n="",s=t.nodeType?[t]:t;a=f.match.PSEUDO.exec(e);)n+=a[0],e=e.replace(f.match.PSEUDO,"");e=f.relative[e]?e+"*":e;for(var r=0,l=s.length;l>r;r++)p(e,s[r],o,i);return p.filter(n,o)};p.attr=O.attr,p.selectors.attrMap={},O.find=p,O.expr=p.selectors,O.expr[":"]=O.expr.filters,O.unique=p.uniqueSort,O.text=p.getText,O.isXMLDoc=p.isXML,O.contains=p.contains}();var lt=/Until$/,ut=/^(?:parents|prevUntil|prevAll)/,ct=/,/,dt=/^.[^:#\[\.,]*$/,pt=Array.prototype.slice,ht=O.expr.match.POS,ft={children:!0,contents:!0,next:!0,prev:!0};O.fn.extend({find:function(e){var t,i,a=this;if("string"!=typeof e)return O(e).filter(function(){for(t=0,i=a.length;i>t;t++)if(O.contains(a[t],this))return!0});var o,n,s,r=this.pushStack("","find",e);for(t=0,i=this.length;i>t;t++)if(o=r.length,O.find(e,this[t],r),t>0)for(n=o;r.length>n;n++)for(s=0;o>s;s++)if(r[s]===r[n]){r.splice(n--,1);break}return r},has:function(e){var t=O(e);return this.filter(function(){for(var e=0,i=t.length;i>e;e++)if(O.contains(this,t[e]))return!0})},not:function(e){return this.pushStack(u(this,e,!1),"not",e)},filter:function(e){return this.pushStack(u(this,e,!0),"filter",e)},is:function(e){return!!e&&("string"==typeof e?ht.test(e)?O(e,this.context).index(this[0])>=0:O.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var i,a,o=[],n=this[0];if(O.isArray(e)){for(var s=1;n&&n.ownerDocument&&n!==t;){for(i=0;e.length>i;i++)O(n).is(e[i])&&o.push({selector:e[i],elem:n,level:s});n=n.parentNode,s++}return o}var r=ht.test(e)||"string"!=typeof e?O(e,t||this.context):0;for(i=0,a=this.length;a>i;i++)for(n=this[i];n;){if(r?r.index(n)>-1:O.find.matchesSelector(n,e)){o.push(n);break}if(n=n.parentNode,!n||!n.ownerDocument||n===t||11===n.nodeType)break}return o=o.length>1?O.unique(o):o,this.pushStack(o,"closest",e)},index:function(e){return e?"string"==typeof e?O.inArray(this[0],O(e)):O.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.prevAll().length:-1},add:function(e,t){var i="string"==typeof e?O(e,t):O.makeArray(e&&e.nodeType?[e]:e),a=O.merge(this.get(),i);return this.pushStack(l(i[0])||l(a[0])?a:O.unique(a))},andSelf:function(){return this.add(this.prevObject)}}),O.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return O.dir(e,"parentNode")},parentsUntil:function(e,t,i){return O.dir(e,"parentNode",i)},next:function(e){return O.nth(e,2,"nextSibling")},prev:function(e){return O.nth(e,2,"previousSibling")},nextAll:function(e){return O.dir(e,"nextSibling")},prevAll:function(e){return O.dir(e,"previousSibling")},nextUntil:function(e,t,i){return O.dir(e,"nextSibling",i)},prevUntil:function(e,t,i){return O.dir(e,"previousSibling",i)},siblings:function(e){return O.sibling(e.parentNode.firstChild,e)},children:function(e){return O.sibling(e.firstChild)},contents:function(e){return O.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:O.makeArray(e.childNodes)}},function(e,t){O.fn[e]=function(i,a){var o=O.map(this,t,i);return lt.test(e)||(a=i),a&&"string"==typeof a&&(o=O.filter(a,o)),o=this.length>1&&!ft[e]?O.unique(o):o,(this.length>1||ct.test(a))&&ut.test(e)&&(o=o.reverse()),this.pushStack(o,e,pt.call(arguments).join(","))}}),O.extend({filter:function(e,t,i){return i&&(e=":not("+e+")"),1===t.length?O.find.matchesSelector(t[0],e)?[t[0]]:[]:O.find.matches(e,t)},dir:function(e,i,a){for(var o=[],n=e[i];n&&9!==n.nodeType&&(a===t||1!==n.nodeType||!O(n).is(a));)1===n.nodeType&&o.push(n),n=n[i];return o},nth:function(e,t,i){t=t||1;for(var a=0;e&&(1!==e.nodeType||++a!==t);e=e[i]);return e},sibling:function(e,t){for(var i=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&i.push(e);return i}});var mt="abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gt=/ jQuery\d+="(?:\d+|null)"/g,vt=/^\s+/,bt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,yt=/<([\w:]+)/,wt=/<tbody/i,kt=/<|&#?\w+;/,_t=/<(?:script|style)/i,xt=/<(?:script|object|embed|option|style)/i,jt=RegExp("<(?:"+mt+")","i"),At=/checked\s*(?:[^=]|=\s*.checked.)/i,Ct=/\/(java|ecma)script/i,St=/^\s*<!(?:\[CDATA\[|\-\-)/,Tt={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]},Et=c(M);Tt.optgroup=Tt.option,Tt.tbody=Tt.tfoot=Tt.colgroup=Tt.caption=Tt.thead,Tt.th=Tt.td,O.support.htmlSerialize||(Tt._default=[1,"div<div>","</div>"]),O.fn.extend({text:function(e){return O.isFunction(e)?this.each(function(t){var i=O(this);i.text(e.call(this,t,i.text()))}):"object"!=typeof e&&e!==t?this.empty().append((this[0]&&this[0].ownerDocument||M).createTextNode(e)):O.text(this)},wrapAll:function(e){if(O.isFunction(e))return this.each(function(t){O(this).wrapAll(e.call(this,t))});if(this[0]){var t=O(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstChild&&1===e.firstChild.nodeType;)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return O.isFunction(e)?this.each(function(t){O(this).wrapInner(e.call(this,t))}):this.each(function(){var t=O(this),i=t.contents();i.length?i.wrapAll(e):t.append(e)})},wrap:function(e){var t=O.isFunction(e);return this.each(function(i){O(this).wrapAll(t?e.call(this,i):e)})},unwrap:function(){return this.parent().each(function(){O.nodeName(this,"body")||O(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){1===this.nodeType&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){1===this.nodeType&&this.insertBefore(e,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this)});if(arguments.length){var e=O.clean(arguments);return e.push.apply(e,this.toArray()),this.pushStack(e,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(e){this.parentNode.insertBefore(e,this.nextSibling)});if(arguments.length){var e=this.pushStack(this,"after",arguments);return e.push.apply(e,O.clean(arguments)),e}},remove:function(e,t){for(var i,a=0;null!=(i=this[a]);a++)(!e||O.filter(e,[i]).length)&&(t||1!==i.nodeType||(O.cleanData(i.getElementsByTagName("*")),O.cleanData([i])),i.parentNode&&i.parentNode.removeChild(i));return this
},empty:function(){for(var e,t=0;null!=(e=this[t]);t++)for(1===e.nodeType&&O.cleanData(e.getElementsByTagName("*"));e.firstChild;)e.removeChild(e.firstChild);return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return O.clone(this,e,t)})},html:function(e){if(e===t)return this[0]&&1===this[0].nodeType?this[0].innerHTML.replace(gt,""):null;if("string"!=typeof e||_t.test(e)||!O.support.leadingWhitespace&&vt.test(e)||Tt[(yt.exec(e)||["",""])[1].toLowerCase()])O.isFunction(e)?this.each(function(t){var i=O(this);i.html(e.call(this,t,i.html()))}):this.empty().append(e);else{e=e.replace(bt,"<$1></$2>");try{for(var i=0,a=this.length;a>i;i++)1===this[i].nodeType&&(O.cleanData(this[i].getElementsByTagName("*")),this[i].innerHTML=e)}catch(o){this.empty().append(e)}}return this},replaceWith:function(e){return this[0]&&this[0].parentNode?O.isFunction(e)?this.each(function(t){var i=O(this),a=i.html();i.replaceWith(e.call(this,t,a))}):("string"!=typeof e&&(e=O(e).detach()),this.each(function(){var t=this.nextSibling,i=this.parentNode;O(this).remove(),t?O(t).before(e):O(i).append(e)})):this.length?this.pushStack(O(O.isFunction(e)?e():e),"replaceWith",e):this},detach:function(e){return this.remove(e,!0)},domManip:function(e,i,a){var o,n,s,r,l=e[0],u=[];if(!O.support.checkClone&&3===arguments.length&&"string"==typeof l&&At.test(l))return this.each(function(){O(this).domManip(e,i,a,!0)});if(O.isFunction(l))return this.each(function(o){var n=O(this);e[0]=l.call(this,o,i?n.html():t),n.domManip(e,i,a)});if(this[0]){if(r=l&&l.parentNode,o=O.support.parentNode&&r&&11===r.nodeType&&r.childNodes.length===this.length?{fragment:r}:O.buildFragment(e,this,u),s=o.fragment,n=1===s.childNodes.length?s=s.firstChild:s.firstChild){i=i&&O.nodeName(n,"tr");for(var c=0,p=this.length,h=p-1;p>c;c++)a.call(i?d(this[c],n):this[c],o.cacheable||p>1&&h>c?O.clone(s,!0,!0):s)}u.length&&O.each(u,b)}return this}}),O.buildFragment=function(e,t,i){var a,o,n,s,r=e[0];return t&&t[0]&&(s=t[0].ownerDocument||t[0]),s.createDocumentFragment||(s=M),!(1===e.length&&"string"==typeof r&&512>r.length&&s===M&&"<"===r.charAt(0))||xt.test(r)||!O.support.checkClone&&At.test(r)||!O.support.html5Clone&&jt.test(r)||(o=!0,n=O.fragments[r],n&&1!==n&&(a=n)),a||(a=s.createDocumentFragment(),O.clean(e,s,a,i)),o&&(O.fragments[r]=n?a:1),{fragment:a,cacheable:o}},O.fragments={},O.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){O.fn[e]=function(i){var a=[],o=O(i),n=1===this.length&&this[0].parentNode;if(n&&11===n.nodeType&&1===n.childNodes.length&&1===o.length)return o[t](this[0]),this;for(var s=0,r=o.length;r>s;s++){var l=(s>0?this.clone(!0):this).get();O(o[s])[t](l),a=a.concat(l)}return this.pushStack(a,e,o.selector)}}),O.extend({clone:function(e,t,i){var a,o,n,s=O.support.html5Clone||!jt.test("<"+e.nodeName)?e.cloneNode(!0):v(e);if(!(O.support.noCloneEvent&&O.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||O.isXMLDoc(e)))for(h(e,s),a=f(e),o=f(s),n=0;a[n];++n)o[n]&&h(a[n],o[n]);if(t&&(p(e,s),i))for(a=f(e),o=f(s),n=0;a[n];++n)p(a[n],o[n]);return a=o=null,s},clean:function(e,i,a,o){var n;i=i||M,i.createElement===t&&(i=i.ownerDocument||i[0]&&i[0].ownerDocument||M);for(var s,r,l=[],u=0;null!=(r=e[u]);u++)if("number"==typeof r&&(r+=""),r){if("string"==typeof r)if(kt.test(r)){r=r.replace(bt,"<$1></$2>");var d=(yt.exec(r)||["",""])[1].toLowerCase(),p=Tt[d]||Tt._default,h=p[0],f=i.createElement("div");for(i===M?Et.appendChild(f):c(i).appendChild(f),f.innerHTML=p[1]+r+p[2];h--;)f=f.lastChild;if(!O.support.tbody){var m=wt.test(r),v="table"!==d||m?"<table>"!==p[1]||m?[]:f.childNodes:f.firstChild&&f.firstChild.childNodes;for(s=v.length-1;s>=0;--s)O.nodeName(v[s],"tbody")&&!v[s].childNodes.length&&v[s].parentNode.removeChild(v[s])}!O.support.leadingWhitespace&&vt.test(r)&&f.insertBefore(i.createTextNode(vt.exec(r)[0]),f.firstChild),r=f.childNodes}else r=i.createTextNode(r);var b;if(!O.support.appendChecked)if(r[0]&&"number"==typeof(b=r.length))for(s=0;b>s;s++)g(r[s]);else g(r);r.nodeType?l.push(r):l=O.merge(l,r)}if(a)for(n=function(e){return!e.type||Ct.test(e.type)},u=0;l[u];u++)if(!o||!O.nodeName(l[u],"script")||l[u].type&&"text/javascript"!==l[u].type.toLowerCase()){if(1===l[u].nodeType){var y=O.grep(l[u].getElementsByTagName("script"),n);l.splice.apply(l,[u+1,0].concat(y))}a.appendChild(l[u])}else o.push(l[u].parentNode?l[u].parentNode.removeChild(l[u]):l[u]);return l},cleanData:function(e){for(var t,i,a,o=O.cache,n=O.event.special,s=O.support.deleteExpando,r=0;null!=(a=e[r]);r++)if((!a.nodeName||!O.noData[a.nodeName.toLowerCase()])&&(i=a[O.expando])){if(t=o[i],t&&t.events){for(var l in t.events)n[l]?O.event.remove(a,l):O.removeEvent(a,l,t.handle);t.handle&&(t.handle.elem=null)}s?delete a[O.expando]:a.removeAttribute&&a.removeAttribute(O.expando),delete o[i]}}});var It,Pt,Dt,Mt=/alpha\([^)]*\)/i,Nt=/opacity=([^)]*)/,$t=/([A-Z]|^ms)/g,Ot=/^-?\d+(?:px)?$/i,Rt=/^-?\d/,zt=/^([\-+])=([\-+.\de]+)/,Lt={position:"absolute",visibility:"hidden",display:"block"},Bt=["Left","Right"],qt=["Top","Bottom"];O.fn.css=function(e,i){return 2===arguments.length&&i===t?this:O.access(this,e,i,!0,function(e,i,a){return a!==t?O.style(e,i,a):O.css(e,i)})},O.extend({cssHooks:{opacity:{get:function(e,t){if(t){var i=It(e,"opacity","opacity");return""===i?"1":i}return e.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":O.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,i,a,o){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var n,s,r=O.camelCase(i),l=e.style,u=O.cssHooks[r];if(i=O.cssProps[r]||r,a===t)return u&&"get"in u&&(n=u.get(e,!1,o))!==t?n:l[i];if(s=typeof a,"string"===s&&(n=zt.exec(a))&&(a=+(n[1]+1)*+n[2]+parseFloat(O.css(e,i)),s="number"),!(null==a||"number"===s&&isNaN(a)||("number"!==s||O.cssNumber[r]||(a+="px"),u&&"set"in u&&(a=u.set(e,a))===t)))try{l[i]=a}catch(c){}}},css:function(e,i,a){var o,n;return i=O.camelCase(i),n=O.cssHooks[i],i=O.cssProps[i]||i,"cssFloat"===i&&(i="float"),n&&"get"in n&&(o=n.get(e,!0,a))!==t?o:It?It(e,i):t},swap:function(e,t,i){var a={};for(var o in t)a[o]=e.style[o],e.style[o]=t[o];i.call(e);for(o in t)e.style[o]=a[o]}}),O.curCSS=O.css,O.each(["height","width"],function(e,i){O.cssHooks[i]={get:function(e,a,o){var n;return a?0!==e.offsetWidth?y(e,i,o):(O.swap(e,Lt,function(){n=y(e,i,o)}),n):t},set:function(e,i){return Ot.test(i)?(i=parseFloat(i),i>=0?i+"px":t):i}}}),O.support.opacity||(O.cssHooks.opacity={get:function(e,t){return Nt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?parseFloat(RegExp.$1)/100+"":t?"1":""},set:function(e,t){var i=e.style,a=e.currentStyle,o=O.isNumeric(t)?"alpha(opacity="+100*t+")":"",n=a&&a.filter||i.filter||"";i.zoom=1,t>=1&&""===O.trim(n.replace(Mt,""))&&i.removeAttribute&&(i.removeAttribute("filter"),a&&!a.filter)||(i.filter=Mt.test(n)?n.replace(Mt,o):n+" "+o)}}),O(function(){O.support.reliableMarginRight||(O.cssHooks.marginRight={get:function(e,t){var i;return O.swap(e,{display:"inline-block"},function(){i=t?It(e,"margin-right","marginRight"):e.style.marginRight}),i}})}),M.defaultView&&M.defaultView.getComputedStyle&&(Pt=function(e,t){var i,a,o;return t=t.replace($t,"-$1").toLowerCase(),(a=e.ownerDocument.defaultView)&&(o=a.getComputedStyle(e,null))&&(i=o.getPropertyValue(t),""!==i||O.contains(e.ownerDocument.documentElement,e)||(i=O.style(e,t))),i}),M.documentElement.currentStyle&&(Dt=function(e,t){var i,a,o,n=e.currentStyle&&e.currentStyle[t],s=e.style;return null===n&&s&&(o=s[t])&&(n=o),!Ot.test(n)&&Rt.test(n)&&(i=s.left,a=e.runtimeStyle&&e.runtimeStyle.left,a&&(e.runtimeStyle.left=e.currentStyle.left),s.left="fontSize"===t?"1em":n||0,n=s.pixelLeft+"px",s.left=i,a&&(e.runtimeStyle.left=a)),""===n?"auto":n}),It=Pt||Dt,O.expr&&O.expr.filters&&(O.expr.filters.hidden=function(e){var t=e.offsetWidth,i=e.offsetHeight;return 0===t&&0===i||!O.support.reliableHiddenOffsets&&"none"===(e.style&&e.style.display||O.css(e,"display"))},O.expr.filters.visible=function(e){return!O.expr.filters.hidden(e)});var Ft,Ht,Ut=/%20/g,Wt=/\[\]$/,Vt=/\r?\n/g,Yt=/#.*$/,Gt=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Kt=/^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,Jt=/^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/,Qt=/^(?:GET|HEAD)$/,Xt=/^\/\//,Zt=/\?/,ei=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,ti=/^(?:select|textarea)/i,ii=/\s+/,ai=/([?&])_=[^&]*/,oi=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,ni=O.fn.load,si={},ri={},li=["*/"]+["*"];try{Ft=$.href}catch(ui){Ft=M.createElement("a"),Ft.href="",Ft=Ft.href}Ht=oi.exec(Ft.toLowerCase())||[],O.fn.extend({load:function(e,i,a){if("string"!=typeof e&&ni)return ni.apply(this,arguments);if(!this.length)return this;var o=e.indexOf(" ");if(o>=0){var n=e.slice(o,e.length);e=e.slice(0,o)}var s="GET";i&&(O.isFunction(i)?(a=i,i=t):"object"==typeof i&&(i=O.param(i,O.ajaxSettings.traditional),s="POST"));var r=this;return O.ajax({url:e,type:s,dataType:"html",data:i,complete:function(e,t,i){i=e.responseText,e.isResolved()&&(e.done(function(e){i=e}),r.html(n?O("<div>").append(i.replace(ei,"")).find(n):i)),a&&r.each(a,[i,t,e])}}),this},serialize:function(){return O.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?O.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ti.test(this.nodeName)||Kt.test(this.type))}).map(function(e,t){var i=O(this).val();return null==i?null:O.isArray(i)?O.map(i,function(e){return{name:t.name,value:e.replace(Vt,"\r\n")}}):{name:t.name,value:i.replace(Vt,"\r\n")}}).get()}}),O.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(e,t){O.fn[t]=function(e){return this.on(t,e)}}),O.each(["get","post"],function(e,i){O[i]=function(e,a,o,n){return O.isFunction(a)&&(n=n||o,o=a,a=t),O.ajax({type:i,url:e,data:a,success:o,dataType:n})}}),O.extend({getScript:function(e,i){return O.get(e,t,i,"script")},getJSON:function(e,t,i){return O.get(e,t,i,"json")},ajaxSetup:function(e,t){return t?_(e,O.ajaxSettings):(t=e,e=O.ajaxSettings),_(e,t),e},ajaxSettings:{url:Ft,isLocal:Jt.test(Ht[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":li},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":O.parseJSON,"text xml":O.parseXML},flatOptions:{context:!0,url:!0}},ajaxPrefilter:w(si),ajaxTransport:w(ri),ajax:function(e,i){function a(e,i,a,s){if(2!==w){w=2,l&&clearTimeout(l),r=t,n=s||"",_.readyState=e>0?4:0;var u,d,b,y,k,x=i,C=a?j(p,_,a):t;if(e>=200&&300>e||304===e)if(p.ifModified&&((y=_.getResponseHeader("Last-Modified"))&&(O.lastModified[o]=y),(k=_.getResponseHeader("Etag"))&&(O.etag[o]=k)),304===e)x="notmodified",u=!0;else try{d=A(p,C),x="success",u=!0}catch(S){x="parsererror",b=S}else b=x,(!x||e)&&(x="error",0>e&&(e=0));_.status=e,_.statusText=""+(i||x),u?m.resolveWith(h,[d,x,_]):m.rejectWith(h,[_,x,b]),_.statusCode(v),v=t,c&&f.trigger("ajax"+(u?"Success":"Error"),[_,p,u?d:b]),g.fireWith(h,[_,x]),c&&(f.trigger("ajaxComplete",[_,p]),--O.active||O.event.trigger("ajaxStop"))}}"object"==typeof e&&(i=e,e=t),i=i||{};var o,n,s,r,l,u,c,d,p=O.ajaxSetup({},i),h=p.context||p,f=h!==p&&(h.nodeType||h instanceof O)?O(h):O.event,m=O.Deferred(),g=O.Callbacks("once memory"),v=p.statusCode||{},b={},y={},w=0,_={readyState:0,setRequestHeader:function(e,t){if(!w){var i=e.toLowerCase();e=y[i]=y[i]||e,b[e]=t}return this},getAllResponseHeaders:function(){return 2===w?n:null},getResponseHeader:function(e){var i;if(2===w){if(!s)for(s={};i=Gt.exec(n);)s[i[1].toLowerCase()]=i[2];i=s[e.toLowerCase()]}return i===t?null:i},overrideMimeType:function(e){return w||(p.mimeType=e),this},abort:function(e){return e=e||"abort",r&&r.abort(e),a(0,e),this}};if(m.promise(_),_.success=_.done,_.error=_.fail,_.complete=g.add,_.statusCode=function(e){if(e){var t;if(2>w)for(t in e)v[t]=[v[t],e[t]];else t=e[_.status],_.then(t,t)}return this},p.url=((e||p.url)+"").replace(Yt,"").replace(Xt,Ht[1]+"//"),p.dataTypes=O.trim(p.dataType||"*").toLowerCase().split(ii),null==p.crossDomain&&(u=oi.exec(p.url.toLowerCase()),p.crossDomain=!(!u||u[1]==Ht[1]&&u[2]==Ht[2]&&(u[3]||("http:"===u[1]?80:443))==(Ht[3]||("http:"===Ht[1]?80:443)))),p.data&&p.processData&&"string"!=typeof p.data&&(p.data=O.param(p.data,p.traditional)),k(si,p,i,_),2===w)return!1;if(c=p.global,p.type=p.type.toUpperCase(),p.hasContent=!Qt.test(p.type),c&&0===O.active++&&O.event.trigger("ajaxStart"),!p.hasContent&&(p.data&&(p.url+=(Zt.test(p.url)?"&":"?")+p.data,delete p.data),o=p.url,p.cache===!1)){var x=O.now(),C=p.url.replace(ai,"$1_="+x);p.url=C+(C===p.url?(Zt.test(p.url)?"&":"?")+"_="+x:"")}(p.data&&p.hasContent&&p.contentType!==!1||i.contentType)&&_.setRequestHeader("Content-Type",p.contentType),p.ifModified&&(o=o||p.url,O.lastModified[o]&&_.setRequestHeader("If-Modified-Since",O.lastModified[o]),O.etag[o]&&_.setRequestHeader("If-None-Match",O.etag[o])),_.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+li+"; q=0.01":""):p.accepts["*"]);for(d in p.headers)_.setRequestHeader(d,p.headers[d]);if(p.beforeSend&&(p.beforeSend.call(h,_,p)===!1||2===w))return _.abort(),!1;for(d in{success:1,error:1,complete:1})_[d](p[d]);if(r=k(ri,p,i,_)){_.readyState=1,c&&f.trigger("ajaxSend",[_,p]),p.async&&p.timeout>0&&(l=setTimeout(function(){_.abort("timeout")},p.timeout));try{w=1,r.send(b,a)}catch(S){if(!(2>w))throw S;a(-1,S)}}else a(-1,"No Transport");return _},param:function(e,i){var a=[],o=function(e,t){t=O.isFunction(t)?t():t,a[a.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(i===t&&(i=O.ajaxSettings.traditional),O.isArray(e)||e.jquery&&!O.isPlainObject(e))O.each(e,function(){o(this.name,this.value)});else for(var n in e)x(n,e[n],i,o);return a.join("&").replace(Ut,"+")}}),O.extend({active:0,lastModified:{},etag:{}});var ci=O.now(),di=/(\=)\?(&|$)|\?\?/i;O.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return O.expando+"_"+ci++}}),O.ajaxPrefilter("json jsonp",function(t,i,a){var o="application/x-www-form-urlencoded"===t.contentType&&"string"==typeof t.data;if("jsonp"===t.dataTypes[0]||t.jsonp!==!1&&(di.test(t.url)||o&&di.test(t.data))){var n,s=t.jsonpCallback=O.isFunction(t.jsonpCallback)?t.jsonpCallback():t.jsonpCallback,r=e[s],l=t.url,u=t.data,c="$1"+s+"$2";return t.jsonp!==!1&&(l=l.replace(di,c),t.url===l&&(o&&(u=u.replace(di,c)),t.data===u&&(l+=(/\?/.test(l)?"&":"?")+t.jsonp+"="+s))),t.url=l,t.data=u,e[s]=function(e){n=[e]},a.always(function(){e[s]=r,n&&O.isFunction(r)&&e[s](n[0])}),t.converters["script json"]=function(){return n||O.error(s+" was not called"),n[0]},t.dataTypes[0]="json","script"}}),O.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(e){return O.globalEval(e),e}}}),O.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),O.ajaxTransport("script",function(e){if(e.crossDomain){var i,a=M.head||M.getElementsByTagName("head")[0]||M.documentElement;return{send:function(o,n){i=M.createElement("script"),i.async="async",e.scriptCharset&&(i.charset=e.scriptCharset),i.src=e.url,i.onload=i.onreadystatechange=function(e,o){(o||!i.readyState||/loaded|complete/.test(i.readyState))&&(i.onload=i.onreadystatechange=null,a&&i.parentNode&&a.removeChild(i),i=t,o||n(200,"success"))},a.insertBefore(i,a.firstChild)},abort:function(){i&&i.onload(0,1)}}}});var pi,hi=e.ActiveXObject?function(){for(var e in pi)pi[e](0,1)}:!1,fi=0;O.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&C()||S()}:C,function(e){O.extend(O.support,{ajax:!!e,cors:!!e&&"withCredentials"in e})}(O.ajaxSettings.xhr()),O.support.ajax&&O.ajaxTransport(function(i){if(!i.crossDomain||O.support.cors){var a;return{send:function(o,n){var s,r,l=i.xhr();if(i.username?l.open(i.type,i.url,i.async,i.username,i.password):l.open(i.type,i.url,i.async),i.xhrFields)for(r in i.xhrFields)l[r]=i.xhrFields[r];i.mimeType&&l.overrideMimeType&&l.overrideMimeType(i.mimeType),i.crossDomain||o["X-Requested-With"]||(o["X-Requested-With"]="XMLHttpRequest");try{for(r in o)l.setRequestHeader(r,o[r])}catch(u){}l.send(i.hasContent&&i.data||null),a=function(e,o){var r,u,c,d,p;try{if(a&&(o||4===l.readyState))if(a=t,s&&(l.onreadystatechange=O.noop,hi&&delete pi[s]),o)4!==l.readyState&&l.abort();else{r=l.status,c=l.getAllResponseHeaders(),d={},p=l.responseXML,p&&p.documentElement&&(d.xml=p),d.text=l.responseText;try{u=l.statusText}catch(h){u=""}r||!i.isLocal||i.crossDomain?1223===r&&(r=204):r=d.text?200:404}}catch(f){o||n(-1,f)}d&&n(r,u,d,c)},i.async&&4!==l.readyState?(s=++fi,hi&&(pi||(pi={},O(e).unload(hi)),pi[s]=a),l.onreadystatechange=a):a()},abort:function(){a&&a(0,1)}}}});var mi,gi,vi,bi,yi={},wi=/^(?:toggle|show|hide)$/,ki=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,_i=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];O.fn.extend({show:function(e,t,i){var a,o;if(e||0===e)return this.animate(I("show",3),e,t,i);for(var n=0,s=this.length;s>n;n++)a=this[n],a.style&&(o=a.style.display,O._data(a,"olddisplay")||"none"!==o||(o=a.style.display=""),""===o&&"none"===O.css(a,"display")&&O._data(a,"olddisplay",P(a.nodeName)));for(n=0;s>n;n++)a=this[n],a.style&&(o=a.style.display,(""===o||"none"===o)&&(a.style.display=O._data(a,"olddisplay")||""));return this},hide:function(e,t,i){if(e||0===e)return this.animate(I("hide",3),e,t,i);for(var a,o,n=0,s=this.length;s>n;n++)a=this[n],a.style&&(o=O.css(a,"display"),"none"===o||O._data(a,"olddisplay")||O._data(a,"olddisplay",o));for(n=0;s>n;n++)this[n].style&&(this[n].style.display="none");return this},_toggle:O.fn.toggle,toggle:function(e,t,i){var a="boolean"==typeof e;return O.isFunction(e)&&O.isFunction(t)?this._toggle.apply(this,arguments):null==e||a?this.each(function(){var t=a?e:O(this).is(":hidden");O(this)[t?"show":"hide"]()}):this.animate(I("toggle",3),e,t,i),this},fadeTo:function(e,t,i,a){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:t},e,i,a)},animate:function(e,t,i,a){function o(){n.queue===!1&&O._mark(this);var t,i,a,o,s,r,l,u,c,d=O.extend({},n),p=1===this.nodeType,h=p&&O(this).is(":hidden");d.animatedProperties={};for(a in e){if(t=O.camelCase(a),a!==t&&(e[t]=e[a],delete e[a]),i=e[t],O.isArray(i)?(d.animatedProperties[t]=i[1],i=e[t]=i[0]):d.animatedProperties[t]=d.specialEasing&&d.specialEasing[t]||d.easing||"swing","hide"===i&&h||"show"===i&&!h)return d.complete.call(this);!p||"height"!==t&&"width"!==t||(d.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],"inline"===O.css(this,"display")&&"none"===O.css(this,"float")&&(O.support.inlineBlockNeedsLayout&&"inline"!==P(this.nodeName)?this.style.zoom=1:this.style.display="inline-block"))}null!=d.overflow&&(this.style.overflow="hidden");for(a in e)o=new O.fx(this,d,a),i=e[a],wi.test(i)?(c=O._data(this,"toggle"+a)||("toggle"===i?h?"show":"hide":0),c?(O._data(this,"toggle"+a,"show"===c?"hide":"show"),o[c]()):o[i]()):(s=ki.exec(i),r=o.cur(),s?(l=parseFloat(s[2]),u=s[3]||(O.cssNumber[a]?"":"px"),"px"!==u&&(O.style(this,a,(l||1)+u),r=(l||1)/o.cur()*r,O.style(this,a,r+u)),s[1]&&(l=("-="===s[1]?-1:1)*l+r),o.custom(r,l,u)):o.custom(r,i,""));return!0}var n=O.speed(t,i,a);return O.isEmptyObject(e)?this.each(n.complete,[!1]):(e=O.extend({},e),n.queue===!1?this.each(o):this.queue(n.queue,o))},stop:function(e,i,a){return"string"!=typeof e&&(a=i,i=e,e=t),i&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){function t(e,t,i){var o=t[i];O.removeData(e,i,!0),o.stop(a)}var i,o=!1,n=O.timers,s=O._data(this);if(a||O._unmark(!0,this),null==e)for(i in s)s[i]&&s[i].stop&&i.indexOf(".run")===i.length-4&&t(this,s,i);else s[i=e+".run"]&&s[i].stop&&t(this,s,i);for(i=n.length;i--;)n[i].elem!==this||null!=e&&n[i].queue!==e||(a?n[i](!0):n[i].saveState(),o=!0,n.splice(i,1));a&&o||O.dequeue(this,e)})}}),O.each({slideDown:I("show",1),slideUp:I("hide",1),slideToggle:I("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){O.fn[e]=function(e,i,a){return this.animate(t,e,i,a)}}),O.extend({speed:function(e,t,i){var a=e&&"object"==typeof e?O.extend({},e):{complete:i||!i&&t||O.isFunction(e)&&e,duration:e,easing:i&&t||t&&!O.isFunction(t)&&t};return a.duration=O.fx.off?0:"number"==typeof a.duration?a.duration:a.duration in O.fx.speeds?O.fx.speeds[a.duration]:O.fx.speeds._default,(null==a.queue||a.queue===!0)&&(a.queue="fx"),a.old=a.complete,a.complete=function(e){O.isFunction(a.old)&&a.old.call(this),a.queue?O.dequeue(this,a.queue):e!==!1&&O._unmark(this)},a},easing:{linear:function(e,t,i,a){return i+a*e},swing:function(e,t,i,a){return(-Math.cos(e*Math.PI)/2+.5)*a+i}},timers:[],fx:function(e,t,i){this.options=t,this.elem=e,this.prop=i,t.orig=t.orig||{}}}),O.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(O.fx.step[this.prop]||O.fx.step._default)(this)},cur:function(){if(null!=this.elem[this.prop]&&(!this.elem.style||null==this.elem.style[this.prop]))return this.elem[this.prop];var e,t=O.css(this.elem,this.prop);return isNaN(e=parseFloat(t))?t&&"auto"!==t?t:0:e},custom:function(e,i,a){function o(e){return n.step(e)}var n=this,s=O.fx;this.startTime=bi||T(),this.end=i,this.now=this.start=e,this.pos=this.state=0,this.unit=a||this.unit||(O.cssNumber[this.prop]?"":"px"),o.queue=this.options.queue,o.elem=this.elem,o.saveState=function(){n.options.hide&&O._data(n.elem,"fxshow"+n.prop)===t&&O._data(n.elem,"fxshow"+n.prop,n.start)},o()&&O.timers.push(o)&&!vi&&(vi=setInterval(s.tick,s.interval))},show:function(){var e=O._data(this.elem,"fxshow"+this.prop);this.options.orig[this.prop]=e||O.style(this.elem,this.prop),this.options.show=!0,e!==t?this.custom(this.cur(),e):this.custom("width"===this.prop||"height"===this.prop?1:0,this.cur()),O(this.elem).show()},hide:function(){this.options.orig[this.prop]=O._data(this.elem,"fxshow"+this.prop)||O.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(e){var t,i,a,o=bi||T(),n=!0,s=this.elem,r=this.options;if(e||o>=r.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),r.animatedProperties[this.prop]=!0;for(t in r.animatedProperties)r.animatedProperties[t]!==!0&&(n=!1);if(n){if(null==r.overflow||O.support.shrinkWrapBlocks||O.each(["","X","Y"],function(e,t){s.style["overflow"+t]=r.overflow[e]}),r.hide&&O(s).hide(),r.hide||r.show)for(t in r.animatedProperties)O.style(s,t,r.orig[t]),O.removeData(s,"fxshow"+t,!0),O.removeData(s,"toggle"+t,!0);a=r.complete,a&&(r.complete=!1,a.call(s))}return!1}return 1/0==r.duration?this.now=o:(i=o-this.startTime,this.state=i/r.duration,this.pos=O.easing[r.animatedProperties[this.prop]](this.state,i,0,1,r.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update(),!0}},O.extend(O.fx,{tick:function(){for(var e,t=O.timers,i=0;t.length>i;i++)e=t[i],e()||t[i]!==e||t.splice(i--,1);t.length||O.fx.stop()},interval:13,stop:function(){clearInterval(vi),vi=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(e){O.style(e.elem,"opacity",e.now)},_default:function(e){e.elem.style&&null!=e.elem.style[e.prop]?e.elem.style[e.prop]=e.now+e.unit:e.elem[e.prop]=e.now}}}),O.each(["width","height"],function(e,t){O.fx.step[t]=function(e){O.style(e.elem,t,Math.max(0,e.now)+e.unit)}}),O.expr&&O.expr.filters&&(O.expr.filters.animated=function(e){return O.grep(O.timers,function(t){return e===t.elem}).length});var xi=/^t(?:able|d|h)$/i,ji=/^(?:body|html)$/i;O.fn.offset="getBoundingClientRect"in M.documentElement?function(e){var t,i=this[0];if(e)return this.each(function(t){O.offset.setOffset(this,e,t)});if(!i||!i.ownerDocument)return null;if(i===i.ownerDocument.body)return O.offset.bodyOffset(i);try{t=i.getBoundingClientRect()}catch(a){}var o=i.ownerDocument,n=o.documentElement;if(!t||!O.contains(n,i))return t?{top:t.top,left:t.left}:{top:0,left:0};var s=o.body,r=D(o),l=n.clientTop||s.clientTop||0,u=n.clientLeft||s.clientLeft||0,c=r.pageYOffset||O.support.boxModel&&n.scrollTop||s.scrollTop,d=r.pageXOffset||O.support.boxModel&&n.scrollLeft||s.scrollLeft,p=t.top+c-l,h=t.left+d-u;return{top:p,left:h}}:function(e){var t=this[0];if(e)return this.each(function(t){O.offset.setOffset(this,e,t)});if(!t||!t.ownerDocument)return null;if(t===t.ownerDocument.body)return O.offset.bodyOffset(t);for(var i,a=t.offsetParent,o=t,n=t.ownerDocument,s=n.documentElement,r=n.body,l=n.defaultView,u=l?l.getComputedStyle(t,null):t.currentStyle,c=t.offsetTop,d=t.offsetLeft;(t=t.parentNode)&&t!==r&&t!==s&&(!O.support.fixedPosition||"fixed"!==u.position);)i=l?l.getComputedStyle(t,null):t.currentStyle,c-=t.scrollTop,d-=t.scrollLeft,t===a&&(c+=t.offsetTop,d+=t.offsetLeft,!O.support.doesNotAddBorder||O.support.doesAddBorderForTableAndCells&&xi.test(t.nodeName)||(c+=parseFloat(i.borderTopWidth)||0,d+=parseFloat(i.borderLeftWidth)||0),o=a,a=t.offsetParent),O.support.subtractsBorderForOverflowNotVisible&&"visible"!==i.overflow&&(c+=parseFloat(i.borderTopWidth)||0,d+=parseFloat(i.borderLeftWidth)||0),u=i;return("relative"===u.position||"static"===u.position)&&(c+=r.offsetTop,d+=r.offsetLeft),O.support.fixedPosition&&"fixed"===u.position&&(c+=Math.max(s.scrollTop,r.scrollTop),d+=Math.max(s.scrollLeft,r.scrollLeft)),{top:c,left:d}},O.offset={bodyOffset:function(e){var t=e.offsetTop,i=e.offsetLeft;return O.support.doesNotIncludeMarginInBodyOffset&&(t+=parseFloat(O.css(e,"marginTop"))||0,i+=parseFloat(O.css(e,"marginLeft"))||0),{top:t,left:i}},setOffset:function(e,t,i){var a=O.css(e,"position");"static"===a&&(e.style.position="relative");var o,n,s=O(e),r=s.offset(),l=O.css(e,"top"),u=O.css(e,"left"),c=("absolute"===a||"fixed"===a)&&O.inArray("auto",[l,u])>-1,d={},p={};c?(p=s.position(),o=p.top,n=p.left):(o=parseFloat(l)||0,n=parseFloat(u)||0),O.isFunction(t)&&(t=t.call(e,i,r)),null!=t.top&&(d.top=t.top-r.top+o),null!=t.left&&(d.left=t.left-r.left+n),"using"in t?t.using.call(e,d):s.css(d)}},O.fn.extend({position:function(){if(!this[0])return null;var e=this[0],t=this.offsetParent(),i=this.offset(),a=ji.test(t[0].nodeName)?{top:0,left:0}:t.offset();return i.top-=parseFloat(O.css(e,"marginTop"))||0,i.left-=parseFloat(O.css(e,"marginLeft"))||0,a.top+=parseFloat(O.css(t[0],"borderTopWidth"))||0,a.left+=parseFloat(O.css(t[0],"borderLeftWidth"))||0,{top:i.top-a.top,left:i.left-a.left}},offsetParent:function(){return this.map(function(){for(var e=this.offsetParent||M.body;e&&!ji.test(e.nodeName)&&"static"===O.css(e,"position");)e=e.offsetParent;return e})}}),O.each(["Left","Top"],function(e,i){var a="scroll"+i;O.fn[a]=function(i){var o,n;return i===t?(o=this[0])?(n=D(o),n?"pageXOffset"in n?n[e?"pageYOffset":"pageXOffset"]:O.support.boxModel&&n.document.documentElement[a]||n.document.body[a]:o[a]):null:this.each(function(){n=D(this),n?n.scrollTo(e?O(n).scrollLeft():i,e?i:O(n).scrollTop()):this[a]=i})}}),O.each(["Height","Width"],function(e,i){var a=i.toLowerCase();O.fn["inner"+i]=function(){var e=this[0];return e?e.style?parseFloat(O.css(e,a,"padding")):this[a]():null},O.fn["outer"+i]=function(e){var t=this[0];return t?t.style?parseFloat(O.css(t,a,e?"margin":"border")):this[a]():null},O.fn[a]=function(e){var o=this[0];if(!o)return null==e?null:this;if(O.isFunction(e))return this.each(function(t){var i=O(this);i[a](e.call(this,t,i[a]()))});if(O.isWindow(o)){var n=o.document.documentElement["client"+i],s=o.document.body;return"CSS1Compat"===o.document.compatMode&&n||s&&s["client"+i]||n}if(9===o.nodeType)return Math.max(o.documentElement["client"+i],o.body["scroll"+i],o.documentElement["scroll"+i],o.body["offset"+i],o.documentElement["offset"+i]);if(e===t){var r=O.css(o,a),l=parseFloat(r);return O.isNumeric(l)?l:r}return this.css(a,"string"==typeof e?e:e+"px")}}),e.jQuery=e.$=O,"function"==typeof define&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return O})})(window);
//     Backbone.js 0.9.2

//     (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc.
//     Backbone may be freely distributed under the MIT license.
//     For all details and documentation:
//     http://backbonejs.org

(function(){

  // Initial Setup
  // -------------

  // Save a reference to the global object (`window` in the browser, `global`
  // on the server).
  var root = this;

  // Save the previous value of the `Backbone` variable, so that it can be
  // restored later on, if `noConflict` is used.
  var previousBackbone = root.Backbone;

  // Create a local reference to slice/splice.
  var slice = Array.prototype.slice;
  var splice = Array.prototype.splice;

  // The top-level namespace. All public Backbone classes and modules will
  // be attached to this. Exported for both CommonJS and the browser.
  var Backbone;
  if (typeof exports !== 'undefined') {
    Backbone = exports;
  } else {
    Backbone = root.Backbone = {};
  }

  // Current version of the library. Keep in sync with `package.json`.
  Backbone.VERSION = '0.9.2';

  // Require Underscore, if we're on the server, and it's not already present.
  var _ = root._;
  if (!_ && (typeof require !== 'undefined')) _ = require('underscore');

  // For Backbone's purposes, jQuery, Zepto, or Ender owns the `$` variable.
  var $ = root.jQuery || root.Zepto || root.ender;

  // Set the JavaScript library that will be used for DOM manipulation and
  // Ajax calls (a.k.a. the `$` variable). By default Backbone will use: jQuery,
  // Zepto, or Ender; but the `setDomLibrary()` method lets you inject an
  // alternate JavaScript library (or a mock library for testing your views
  // outside of a browser).
  Backbone.setDomLibrary = function(lib) {
    $ = lib;
  };

  // Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
  // to its previous owner. Returns a reference to this Backbone object.
  Backbone.noConflict = function() {
    root.Backbone = previousBackbone;
    return this;
  };

  // Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option
  // will fake `"PUT"` and `"DELETE"` requests via the `_method` parameter and
  // set a `X-Http-Method-Override` header.
  Backbone.emulateHTTP = false;

  // Turn on `emulateJSON` to support legacy servers that can't deal with direct
  // `application/json` requests ... will encode the body as
  // `application/x-www-form-urlencoded` instead and will send the model in a
  // form param named `model`.
  Backbone.emulateJSON = false;

  // Backbone.Events
  // -----------------

  // Regular expression used to split event strings
  var eventSplitter = /\s+/;

  // A module that can be mixed in to *any object* in order to provide it with
  // custom events. You may bind with `on` or remove with `off` callback functions
  // to an event; trigger`-ing an event fires all callbacks in succession.
  //
  //     var object = {};
  //     _.extend(object, Backbone.Events);
  //     object.on('expand', function(){ alert('expanded'); });
  //     object.trigger('expand');
  //
  var Events = Backbone.Events = {

    // Bind one or more space separated events, `events`, to a `callback`
    // function. Passing `"all"` will bind the callback to all events fired.
    on: function(events, callback, context) {

      var calls, event, node, tail, list;
      if (!callback) return this;
      events = events.split(eventSplitter);
      calls = this._callbacks || (this._callbacks = {});

      // Create an immutable callback list, allowing traversal during
      // modification.  The tail is an empty object that will always be used
      // as the next node.
      while (event = events.shift()) {
        list = calls[event];
        node = list ? list.tail : {};
        node.next = tail = {};
        node.context = context;
        node.callback = callback;
        calls[event] = {tail: tail, next: list ? list.next : node};
      }

      return this;
    },

    // Remove one or many callbacks. If `context` is null, removes all callbacks
    // with that function. If `callback` is null, removes all callbacks for the
    // event. If `events` is null, removes all bound callbacks for all events.
    off: function(events, callback, context) {
      var event, calls, node, tail, cb, ctx;

      // No events, or removing *all* events.
      if (!(calls = this._callbacks)) return;
      if (!(events || callback || context)) {
        delete this._callbacks;
        return this;
      }

      // Loop through the listed events and contexts, splicing them out of the
      // linked list of callbacks if appropriate.
      events = events ? events.split(eventSplitter) : _.keys(calls);
      while (event = events.shift()) {
        node = calls[event];
        delete calls[event];
        if (!node || !(callback || context)) continue;
        // Create a new list, omitting the indicated callbacks.
        tail = node.tail;
        while ((node = node.next) !== tail) {
          cb = node.callback;
          ctx = node.context;
          if ((callback && cb !== callback) || (context && ctx !== context)) {
            this.on(event, cb, ctx);
          }
        }
      }

      return this;
    },

    // Trigger one or many events, firing all bound callbacks. Callbacks are
    // passed the same arguments as `trigger` is, apart from the event name
    // (unless you're listening on `"all"`, which will cause your callback to
    // receive the true name of the event as the first argument).
    trigger: function(events) {
      var event, node, calls, tail, args, all, rest;
      if (!(calls = this._callbacks)) return this;
      all = calls.all;
      events = events.split(eventSplitter);
      rest = slice.call(arguments, 1);

      // For each event, walk through the linked list of callbacks twice,
      // first to trigger the event, then to trigger any `"all"` callbacks.
      while (event = events.shift()) {
        if (node = calls[event]) {
          tail = node.tail;
          while ((node = node.next) !== tail) {
            node.callback.apply(node.context || this, rest);
          }
        }
        if (node = all) {
          tail = node.tail;
          args = [event].concat(rest);
          while ((node = node.next) !== tail) {
            node.callback.apply(node.context || this, args);
          }
        }
      }

      return this;
    }

  };

  // Aliases for backwards compatibility.
  Events.bind   = Events.on;
  Events.unbind = Events.off;

  // Backbone.Model
  // --------------

  // Create a new model, with defined attributes. A client id (`cid`)
  // is automatically generated and assigned for you.
  var Model = Backbone.Model = function(attributes, options) {
    var defaults;
    attributes || (attributes = {});
    if (options && options.parse) attributes = this.parse(attributes);
    if (defaults = getValue(this, 'defaults')) {
      attributes = _.extend({}, defaults, attributes);
    }
    if (options && options.collection) this.collection = options.collection;
    this.attributes = {};
    this._escapedAttributes = {};
    this.cid = _.uniqueId('c');
    this.changed = {};
    this._silent = {};
    this._pending = {};
    this.set(attributes, {silent: true});
    // Reset change tracking.
    this.changed = {};
    this._silent = {};
    this._pending = {};
    this._previousAttributes = _.clone(this.attributes);
    this.initialize.apply(this, arguments);
  };

  // Attach all inheritable methods to the Model prototype.
  _.extend(Model.prototype, Events, {

    // A hash of attributes whose current and previous value differ.
    changed: null,

    // A hash of attributes that have silently changed since the last time
    // `change` was called.  Will become pending attributes on the next call.
    _silent: null,

    // A hash of attributes that have changed since the last `'change'` event
    // began.
    _pending: null,

    // The default name for the JSON `id` attribute is `"id"`. MongoDB and
    // CouchDB users may want to set this to `"_id"`.
    idAttribute: 'id',

    // Initialize is an empty function by default. Override it with your own
    // initialization logic.
    initialize: function(){},

    // Return a copy of the model's `attributes` object.
    toJSON: function(options) {
      return _.clone(this.attributes);
    },

    // Get the value of an attribute.
    get: function(attr) {
      return this.attributes[attr];
    },

    // Get the HTML-escaped value of an attribute.
    escape: function(attr) {
      var html;
      if (html = this._escapedAttributes[attr]) return html;
      var val = this.get(attr);
      return this._escapedAttributes[attr] = _.escape(val == null ? '' : '' + val);
    },

    // Returns `true` if the attribute contains a value that is not null
    // or undefined.
    has: function(attr) {
      return this.get(attr) != null;
    },

    // Set a hash of model attributes on the object, firing `"change"` unless
    // you choose to silence it.
    set: function(key, value, options) {
      var attrs, attr, val;

      // Handle both `"key", value` and `{key: value}` -style arguments.
      if (_.isObject(key) || key == null) {
        attrs = key;
        options = value;
      } else {
        attrs = {};
        attrs[key] = value;
      }

      // Extract attributes and options.
      options || (options = {});
      if (!attrs) return this;
      if (attrs instanceof Model) attrs = attrs.attributes;
      if (options.unset) for (attr in attrs) attrs[attr] = void 0;

      // Run validation.
      if (!this._validate(attrs, options)) return false;

      // Check for changes of `id`.
      if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];

      var changes = options.changes = {};
      var now = this.attributes;
      var escaped = this._escapedAttributes;
      var prev = this._previousAttributes || {};

      // For each `set` attribute...
      for (attr in attrs) {
        val = attrs[attr];

        // If the new and current value differ, record the change.
        if (!_.isEqual(now[attr], val) || (options.unset && _.has(now, attr))) {
          delete escaped[attr];
          (options.silent ? this._silent : changes)[attr] = true;
        }

        // Update or delete the current value.
        options.unset ? delete now[attr] : now[attr] = val;

        // If the new and previous value differ, record the change.  If not,
        // then remove changes for this attribute.
        if (!_.isEqual(prev[attr], val) || (_.has(now, attr) != _.has(prev, attr))) {
          this.changed[attr] = val;
          if (!options.silent) this._pending[attr] = true;
        } else {
          delete this.changed[attr];
          delete this._pending[attr];
        }
      }

      // Fire the `"change"` events.
      if (!options.silent) this.change(options);
      return this;
    },

    // Remove an attribute from the model, firing `"change"` unless you choose
    // to silence it. `unset` is a noop if the attribute doesn't exist.
    unset: function(attr, options) {
      (options || (options = {})).unset = true;
      return this.set(attr, null, options);
    },

    // Clear all attributes on the model, firing `"change"` unless you choose
    // to silence it.
    clear: function(options) {
      (options || (options = {})).unset = true;
      return this.set(_.clone(this.attributes), options);
    },

    // Fetch the model from the server. If the server's representation of the
    // model differs from its current attributes, they will be overriden,
    // triggering a `"change"` event.
    fetch: function(options) {
      options = options ? _.clone(options) : {};
      var model = this;
      var success = options.success;
      options.success = function(resp, status, xhr) {
        if (!model.set(model.parse(resp, xhr), options)) return false;
        if (success) success(model, resp);
      };
      options.error = Backbone.wrapError(options.error, model, options);
      return (this.sync || Backbone.sync).call(this, 'read', this, options);
    },

    // Set a hash of model attributes, and sync the model to the server.
    // If the server returns an attributes hash that differs, the model's
    // state will be `set` again.
    save: function(key, value, options) {
      var attrs, current;

      // Handle both `("key", value)` and `({key: value})` -style calls.
      if (_.isObject(key) || key == null) {
        attrs = key;
        options = value;
      } else {
        attrs = {};
        attrs[key] = value;
      }
      options = options ? _.clone(options) : {};

      // If we're "wait"-ing to set changed attributes, validate early.
      if (options.wait) {
        if (!this._validate(attrs, options)) return false;
        current = _.clone(this.attributes);
      }

      // Regular saves `set` attributes before persisting to the server.
      var silentOptions = _.extend({}, options, {silent: true});
      if (attrs && !this.set(attrs, options.wait ? silentOptions : options)) {
        return false;
      }

      // After a successful server-side save, the client is (optionally)
      // updated with the server-side state.
      var model = this;
      var success = options.success;
      options.success = function(resp, status, xhr) {
        var serverAttrs = model.parse(resp, xhr);
        if (options.wait) {
          delete options.wait;
          serverAttrs = _.extend(attrs || {}, serverAttrs);
        }
        if (!model.set(serverAttrs, options)) return false;
        if (success) {
          success(model, resp);
        } else {
          model.trigger('sync', model, resp, options);
        }
      };

      // Finish configuring and sending the Ajax request.
      options.error = Backbone.wrapError(options.error, model, options);
      var method = this.isNew() ? 'create' : 'update';
      var xhr = (this.sync || Backbone.sync).call(this, method, this, options);
      if (options.wait) this.set(current, silentOptions);
      return xhr;
    },

    // Destroy this model on the server if it was already persisted.
    // Optimistically removes the model from its collection, if it has one.
    // If `wait: true` is passed, waits for the server to respond before removal.
    destroy: function(options) {
      options = options ? _.clone(options) : {};
      var model = this;
      var success = options.success;

      var triggerDestroy = function() {
        model.trigger('destroy', model, model.collection, options);
      };

      if (this.isNew()) {
        triggerDestroy();
        return false;
      }

      options.success = function(resp) {
        if (options.wait) triggerDestroy();
        if (success) {
          success(model, resp);
        } else {
          model.trigger('sync', model, resp, options);
        }
      };

      options.error = Backbone.wrapError(options.error, model, options);
      var xhr = (this.sync || Backbone.sync).call(this, 'delete', this, options);
      if (!options.wait) triggerDestroy();
      return xhr;
    },

    // Default URL for the model's representation on the server -- if you're
    // using Backbone's restful methods, override this to change the endpoint
    // that will be called.
    url: function() {
      var base = getValue(this, 'urlRoot') || getValue(this.collection, 'url') || urlError();
      if (this.isNew()) return base;
      return base + (base.charAt(base.length - 1) == '/' ? '' : '/') + encodeURIComponent(this.id);
    },

    // **parse** converts a response into the hash of attributes to be `set` on
    // the model. The default implementation is just to pass the response along.
    parse: function(resp, xhr) {
      return resp;
    },

    // Create a new model with identical attributes to this one.
    clone: function() {
      return new this.constructor(this.attributes);
    },

    // A model is new if it has never been saved to the server, and lacks an id.
    isNew: function() {
      return this.id == null;
    },

    // Call this method to manually fire a `"change"` event for this model and
    // a `"change:attribute"` event for each changed attribute.
    // Calling this will cause all objects observing the model to update.
    change: function(options) {
      options || (options = {});
      var changing = this._changing;
      this._changing = true;

      // Silent changes become pending changes.
      for (var attr in this._silent) this._pending[attr] = true;

      // Silent changes are triggered.
      var changes = _.extend({}, options.changes, this._silent);
      this._silent = {};
      for (var attr in changes) {
        this.trigger('change:' + attr, this, this.get(attr), options);
      }
      if (changing) return this;

      // Continue firing `"change"` events while there are pending changes.
      while (!_.isEmpty(this._pending)) {
        this._pending = {};
        this.trigger('change', this, options);
        // Pending and silent changes still remain.
        for (var attr in this.changed) {
          if (this._pending[attr] || this._silent[attr]) continue;
          delete this.changed[attr];
        }
        this._previousAttributes = _.clone(this.attributes);
      }

      this._changing = false;
      return this;
    },

    // Determine if the model has changed since the last `"change"` event.
    // If you specify an attribute name, determine if that attribute has changed.
    hasChanged: function(attr) {
      if (!arguments.length) return !_.isEmpty(this.changed);
      return _.has(this.changed, attr);
    },

    // Return an object containing all the attributes that have changed, or
    // false if there are no changed attributes. Useful for determining what
    // parts of a view need to be updated and/or what attributes need to be
    // persisted to the server. Unset attributes will be set to undefined.
    // You can also pass an attributes object to diff against the model,
    // determining if there *would be* a change.
    changedAttributes: function(diff) {
      if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;
      var val, changed = false, old = this._previousAttributes;
      for (var attr in diff) {
        if (_.isEqual(old[attr], (val = diff[attr]))) continue;
        (changed || (changed = {}))[attr] = val;
      }
      return changed;
    },

    // Get the previous value of an attribute, recorded at the time the last
    // `"change"` event was fired.
    previous: function(attr) {
      if (!arguments.length || !this._previousAttributes) return null;
      return this._previousAttributes[attr];
    },

    // Get all of the attributes of the model at the time of the previous
    // `"change"` event.
    previousAttributes: function() {
      return _.clone(this._previousAttributes);
    },

    // Check if the model is currently in a valid state. It's only possible to
    // get into an *invalid* state if you're using silent changes.
    isValid: function() {
      return !this.validate(this.attributes);
    },

    // Run validation against the next complete set of model attributes,
    // returning `true` if all is well. If a specific `error` callback has
    // been passed, call that instead of firing the general `"error"` event.
    _validate: function(attrs, options) {
      if (options.silent || !this.validate) return true;
      attrs = _.extend({}, this.attributes, attrs);
      var error = this.validate(attrs, options);
      if (!error) return true;
      if (options && options.error) {
        options.error(this, error, options);
      } else {
        this.trigger('error', this, error, options);
      }
      return false;
    }

  });

  // Backbone.Collection
  // -------------------

  // Provides a standard collection class for our sets of models, ordered
  // or unordered. If a `comparator` is specified, the Collection will maintain
  // its models in sort order, as they're added and removed.
  var Collection = Backbone.Collection = function(models, options) {
    options || (options = {});
    if (options.model) this.model = options.model;
    if (options.comparator) this.comparator = options.comparator;
    this._reset();
    this.initialize.apply(this, arguments);
    if (models) this.reset(models, {silent: true, parse: options.parse});
  };

  // Define the Collection's inheritable methods.
  _.extend(Collection.prototype, Events, {

    // The default model for a collection is just a **Backbone.Model**.
    // This should be overridden in most cases.
    model: Model,

    // Initialize is an empty function by default. Override it with your own
    // initialization logic.
    initialize: function(){},

    // The JSON representation of a Collection is an array of the
    // models' attributes.
    toJSON: function(options) {
      return this.map(function(model){ return model.toJSON(options); });
    },

    // Add a model, or list of models to the set. Pass **silent** to avoid
    // firing the `add` event for every new model.
    add: function(models, options) {
      var i, index, length, model, cid, id, cids = {}, ids = {}, dups = [];
      options || (options = {});
      models = _.isArray(models) ? models.slice() : [models];

      // Begin by turning bare objects into model references, and preventing
      // invalid models or duplicate models from being added.
      for (i = 0, length = models.length; i < length; i++) {
        if (!(model = models[i] = this._prepareModel(models[i], options))) {
          throw new Error("Can't add an invalid model to a collection");
        }
        cid = model.cid;
        id = model.id;
        if (cids[cid] || this._byCid[cid] || ((id != null) && (ids[id] || this._byId[id]))) {
          dups.push(i);
          continue;
        }
        cids[cid] = ids[id] = model;
      }

      // Remove duplicates.
      i = dups.length;
      while (i--) {
        models.splice(dups[i], 1);
      }

      // Listen to added models' events, and index models for lookup by
      // `id` and by `cid`.
      for (i = 0, length = models.length; i < length; i++) {
        (model = models[i]).on('all', this._onModelEvent, this);
        this._byCid[model.cid] = model;
        if (model.id != null) this._byId[model.id] = model;
      }

      // Insert models into the collection, re-sorting if needed, and triggering
      // `add` events unless silenced.
      this.length += length;
      index = options.at != null ? options.at : this.models.length;
      splice.apply(this.models, [index, 0].concat(models));
      if (this.comparator) this.sort({silent: true});
      if (options.silent) return this;
      for (i = 0, length = this.models.length; i < length; i++) {
        if (!cids[(model = this.models[i]).cid]) continue;
        options.index = i;
        model.trigger('add', model, this, options);
      }
      return this;
    },

    // Remove a model, or a list of models from the set. Pass silent to avoid
    // firing the `remove` event for every model removed.
    remove: function(models, options) {
      var i, l, index, model;
      options || (options = {});
      models = _.isArray(models) ? models.slice() : [models];
      for (i = 0, l = models.length; i < l; i++) {
        model = this.getByCid(models[i]) || this.get(models[i]);
        if (!model) continue;
        delete this._byId[model.id];
        delete this._byCid[model.cid];
        index = this.indexOf(model);
        this.models.splice(index, 1);
        this.length--;
        if (!options.silent) {
          options.index = index;
          model.trigger('remove', model, this, options);
        }
        this._removeReference(model);
      }
      return this;
    },

    // Add a model to the end of the collection.
    push: function(model, options) {
      model = this._prepareModel(model, options);
      this.add(model, options);
      return model;
    },

    // Remove a model from the end of the collection.
    pop: function(options) {
      var model = this.at(this.length - 1);
      this.remove(model, options);
      return model;
    },

    // Add a model to the beginning of the collection.
    unshift: function(model, options) {
      model = this._prepareModel(model, options);
      this.add(model, _.extend({at: 0}, options));
      return model;
    },

    // Remove a model from the beginning of the collection.
    shift: function(options) {
      var model = this.at(0);
      this.remove(model, options);
      return model;
    },

    // Get a model from the set by id.
    get: function(id) {
      if (id == null) return void 0;
      return this._byId[id.id != null ? id.id : id];
    },

    // Get a model from the set by client id.
    getByCid: function(cid) {
      return cid && this._byCid[cid.cid || cid];
    },

    // Get the model at the given index.
    at: function(index) {
      return this.models[index];
    },

    // Return models with matching attributes. Useful for simple cases of `filter`.
    where: function(attrs) {
      if (_.isEmpty(attrs)) return [];
      return this.filter(function(model) {
        for (var key in attrs) {
          if (attrs[key] !== model.get(key)) return false;
        }
        return true;
      });
    },

    // Force the collection to re-sort itself. You don't need to call this under
    // normal circumstances, as the set will maintain sort order as each item
    // is added.
    sort: function(options) {
      options || (options = {});
      if (!this.comparator) throw new Error('Cannot sort a set without a comparator');
      var boundComparator = _.bind(this.comparator, this);
      if (this.comparator.length == 1) {
        this.models = this.sortBy(boundComparator);
      } else {
        this.models.sort(boundComparator);
      }
      if (!options.silent) this.trigger('reset', this, options);
      return this;
    },

    // Pluck an attribute from each model in the collection.
    pluck: function(attr) {
      return _.map(this.models, function(model){ return model.get(attr); });
    },

    // When you have more items than you want to add or remove individually,
    // you can reset the entire set with a new list of models, without firing
    // any `add` or `remove` events. Fires `reset` when finished.
    reset: function(models, options) {
      models  || (models = []);
      options || (options = {});
      for (var i = 0, l = this.models.length; i < l; i++) {
        this._removeReference(this.models[i]);
      }
      this._reset();
      this.add(models, _.extend({silent: true}, options));
      if (!options.silent) this.trigger('reset', this, options);
      return this;
    },

    // Fetch the default set of models for this collection, resetting the
    // collection when they arrive. If `add: true` is passed, appends the
    // models to the collection instead of resetting.
    fetch: function(options) {
      options = options ? _.clone(options) : {};
      if (options.parse === undefined) options.parse = true;
      var collection = this;
      var success = options.success;
      options.success = function(resp, status, xhr) {
        collection[options.add ? 'add' : 'reset'](collection.parse(resp, xhr), options);
        if (success) success(collection, resp);
      };
      options.error = Backbone.wrapError(options.error, collection, options);
      return (this.sync || Backbone.sync).call(this, 'read', this, options);
    },

    // Create a new instance of a model in this collection. Add the model to the
    // collection immediately, unless `wait: true` is passed, in which case we
    // wait for the server to agree.
    create: function(model, options) {
      var coll = this;
      options = options ? _.clone(options) : {};
      model = this._prepareModel(model, options);
      if (!model) return false;
      if (!options.wait) coll.add(model, options);
      var success = options.success;
      options.success = function(nextModel, resp, xhr) {
        if (options.wait) coll.add(nextModel, options);
        if (success) {
          success(nextModel, resp);
        } else {
          nextModel.trigger('sync', model, resp, options);
        }
      };
      model.save(null, options);
      return model;
    },

    // **parse** converts a response into a list of models to be added to the
    // collection. The default implementation is just to pass it through.
    parse: function(resp, xhr) {
      return resp;
    },

    // Proxy to _'s chain. Can't be proxied the same way the rest of the
    // underscore methods are proxied because it relies on the underscore
    // constructor.
    chain: function () {
      return _(this.models).chain();
    },

    // Reset all internal state. Called when the collection is reset.
    _reset: function(options) {
      this.length = 0;
      this.models = [];
      this._byId  = {};
      this._byCid = {};
    },

    // Prepare a model or hash of attributes to be added to this collection.
    _prepareModel: function(model, options) {
      options || (options = {});
      if (!(model instanceof Model)) {
        var attrs = model;
        options.collection = this;
        model = new this.model(attrs, options);
        if (!model._validate(model.attributes, options)) model = false;
      } else if (!model.collection) {
        model.collection = this;
      }
      return model;
    },

    // Internal method to remove a model's ties to a collection.
    _removeReference: function(model) {
      if (this == model.collection) {
        delete model.collection;
      }
      model.off('all', this._onModelEvent, this);
    },

    // Internal method called every time a model in the set fires an event.
    // Sets need to update their indexes when models change ids. All other
    // events simply proxy through. "add" and "remove" events that originate
    // in other collections are ignored.
    _onModelEvent: function(event, model, collection, options) {
      if ((event == 'add' || event == 'remove') && collection != this) return;
      if (event == 'destroy') {
        this.remove(model, options);
      }
      if (model && event === 'change:' + model.idAttribute) {
        delete this._byId[model.previous(model.idAttribute)];
        this._byId[model.id] = model;
      }
      this.trigger.apply(this, arguments);
    }

  });

  // Underscore methods that we want to implement on the Collection.
  var methods = ['forEach', 'each', 'map', 'reduce', 'reduceRight', 'find',
    'detect', 'filter', 'select', 'reject', 'every', 'all', 'some', 'any',
    'include', 'contains', 'invoke', 'max', 'min', 'sortBy', 'sortedIndex',
    'toArray', 'size', 'first', 'initial', 'rest', 'last', 'without', 'indexOf',
    'shuffle', 'lastIndexOf', 'isEmpty', 'groupBy'];

  // Mix in each Underscore method as a proxy to `Collection#models`.
  _.each(methods, function(method) {
    Collection.prototype[method] = function() {
      return _[method].apply(_, [this.models].concat(_.toArray(arguments)));
    };
  });

  // Backbone.Router
  // -------------------

  // Routers map faux-URLs to actions, and fire events when routes are
  // matched. Creating a new one sets its `routes` hash, if not set statically.
  var Router = Backbone.Router = function(options) {
    options || (options = {});
    if (options.routes) this.routes = options.routes;
    this._bindRoutes();
    this.initialize.apply(this, arguments);
  };

  // Cached regular expressions for matching named param parts and splatted
  // parts of route strings.
  var namedParam    = /:\w+/g;
  var splatParam    = /\*\w+/g;
  var escapeRegExp  = /[-[\]{}()+?.,\\^$|#\s]/g;

  // Set up all inheritable **Backbone.Router** properties and methods.
  _.extend(Router.prototype, Events, {

    // Initialize is an empty function by default. Override it with your own
    // initialization logic.
    initialize: function(){},

    // Manually bind a single named route to a callback. For example:
    //
    //     this.route('search/:query/p:num', 'search', function(query, num) {
    //       ...
    //     });
    //
    route: function(route, name, callback) {
      Backbone.history || (Backbone.history = new History);
      if (!_.isRegExp(route)) route = this._routeToRegExp(route);
      if (!callback) callback = this[name];
      Backbone.history.route(route, _.bind(function(fragment) {
        var args = this._extractParameters(route, fragment);
        callback && callback.apply(this, args);
        this.trigger.apply(this, ['route:' + name].concat(args));
        Backbone.history.trigger('route', this, name, args);
      }, this));
      return this;
    },

    // Simple proxy to `Backbone.history` to save a fragment into the history.
    navigate: function(fragment, options) {
      Backbone.history.navigate(fragment, options);
    },

    // Bind all defined routes to `Backbone.history`. We have to reverse the
    // order of the routes here to support behavior where the most general
    // routes can be defined at the bottom of the route map.
    _bindRoutes: function() {
      if (!this.routes) return;
      var routes = [];
      for (var route in this.routes) {
        routes.unshift([route, this.routes[route]]);
      }
      for (var i = 0, l = routes.length; i < l; i++) {
        this.route(routes[i][0], routes[i][1], this[routes[i][1]]);
      }
    },

    // Convert a route string into a regular expression, suitable for matching
    // against the current location hash.
    _routeToRegExp: function(route) {
      // huy@coursera 2013-01-22 Ignore query string
      //route = route.replace(escapeRegExp, '\\$&')
      //  .replace(namedParam, '([^\/]+)')
      //  .replace(splatParam, '(.*?)');
      //return new RegExp('^' + route + '$');
      route = route.replace(escapeRegExp, '\\$&')
                   .replace(namedParam, '([^\/?]+)')
                   .replace(splatParam, '(.*?)');
      return new RegExp('^' + route + '(?:\\?.*)?$');
    },

    // Given a route, and a URL fragment that it matches, return the array of
    // extracted parameters.
    _extractParameters: function(route, fragment) {
      return route.exec(fragment).slice(1);
    }

  });

  // Backbone.History
  // ----------------

  // Handles cross-browser history management, based on URL fragments. If the
  // browser does not support `onhashchange`, falls back to polling.
  var History = Backbone.History = function() {
    this.handlers = [];
    _.bindAll(this, 'checkUrl');
  };

  // Cached regex for cleaning leading hashes and slashes .
  var routeStripper = /^[#\/]/;

  // Cached regex for detecting MSIE.
  var isExplorer = /msie [\w.]+/;

  // Has the history handling already been started?
  History.started = false;

  // Set up all inheritable **Backbone.History** properties and methods.
  _.extend(History.prototype, Events, {

    // The default interval to poll for hash changes, if necessary, is
    // twenty times a second.
    interval: 50,

    // Gets the true hash value. Cannot use location.hash directly due to bug
    // in Firefox where location.hash will always be decoded.
    getHash: function(windowOverride) {
      var loc = windowOverride ? windowOverride.location : window.location;
      var match = loc.href.match(/#(.*)$/);
      return match ? match[1] : '';
    },

    // Get the cross-browser normalized URL fragment, either from the URL,
    // the hash, or the override.
    getFragment: function(fragment, forcePushState) {
      if (fragment == null) {
        if (this._hasPushState || forcePushState) {
          fragment = window.location.pathname;
          var search = window.location.search;
          if (search) fragment += search;
        } else {
          fragment = this.getHash();
        }
      }
      if (!fragment.indexOf(this.options.root)) fragment = fragment.substr(this.options.root.length);
      return fragment.replace(routeStripper, '');
    },

    // Start the hash change handling, returning `true` if the current URL matches
    // an existing route, and `false` otherwise.
    start: function(options) {
      if (History.started) throw new Error("Backbone.history has already been started");
      History.started = true;

      // Figure out the initial configuration. Do we need an iframe?
      // Is pushState desired ... is it available?
      this.options          = _.extend({}, {root: '/'}, this.options, options);
      this._wantsHashChange = this.options.hashChange !== false;
      this._wantsPushState  = !!this.options.pushState;
      this._hasPushState    = !!(this.options.pushState && window.history && window.history.pushState);
      var fragment          = this.getFragment();
      var docMode           = document.documentMode;
      var oldIE             = (isExplorer.exec(navigator.userAgent.toLowerCase()) && (!docMode || docMode <= 7));

      if (oldIE) {
        this.iframe = $('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo('body')[0].contentWindow;
        this.navigate(fragment);
      }

      // Depending on whether we're using pushState or hashes, and whether
      // 'onhashchange' is supported, determine how we check the URL state.
      if (this._hasPushState) {
        $(window).bind('popstate', this.checkUrl);
      } else if (this._wantsHashChange && ('onhashchange' in window) && !oldIE) {
        $(window).bind('hashchange', this.checkUrl);
      } else if (this._wantsHashChange) {
        this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
      }

      // Determine if we need to change the base url, for a pushState link
      // opened by a non-pushState browser.
      this.fragment = fragment;
      var loc = window.location;
      var atRoot  = loc.pathname == this.options.root;

      // If we've started off with a route from a `pushState`-enabled browser,
      // but we're currently in a browser that doesn't support it...
      if (this._wantsHashChange && this._wantsPushState && !this._hasPushState && !atRoot) {
        this.fragment = this.getFragment(null, true);
        window.location.replace(this.options.root + '#' + this.fragment);
        // Return immediately as browser will do redirect to new url
        return true;

      // Or if we've started out with a hash-based route, but we're currently
      // in a browser where it could be `pushState`-based instead...
      } else if (this._wantsPushState && this._hasPushState && atRoot && loc.hash) {
        this.fragment = this.getHash().replace(routeStripper, '');
        window.history.replaceState({}, document.title, loc.protocol + '//' + loc.host + this.options.root + this.fragment);
      }

      if (!this.options.silent) {
        return this.loadUrl();
      }
    },

    // Disable Backbone.history, perhaps temporarily. Not useful in a real app,
    // but possibly useful for unit testing Routers.
    stop: function() {
      $(window).unbind('popstate', this.checkUrl).unbind('hashchange', this.checkUrl);
      clearInterval(this._checkUrlInterval);
      History.started = false;
    },

    // Add a route to be tested when the fragment changes. Routes added later
    // may override previous routes.
    route: function(route, callback) {
      this.handlers.unshift({route: route, callback: callback});
    },

    // Checks the current URL to see if it has changed, and if it has,
    // calls `loadUrl`, normalizing across the hidden iframe.
    checkUrl: function(e) {
      var current = this.getFragment();
      if (current == this.fragment && this.iframe) current = this.getFragment(this.getHash(this.iframe));
      if (current == this.fragment) return false;
      if (this.iframe) this.navigate(current);
      this.loadUrl() || this.loadUrl(this.getHash());
    },

    // Attempt to load the current URL fragment. If a route succeeds with a
    // match, returns `true`. If no defined routes matches the fragment,
    // returns `false`.
    loadUrl: function(fragmentOverride) {
      var fragment = this.fragment = this.getFragment(fragmentOverride);
      var matched = _.any(this.handlers, function(handler) {
        if (handler.route.test(fragment)) {
          handler.callback(fragment);
          return true;
        }
      });
      return matched;
    },

    // Save a fragment into the hash history, or replace the URL state if the
    // 'replace' option is passed. You are responsible for properly URL-encoding
    // the fragment in advance.
    //
    // The options object can contain `trigger: true` if you wish to have the
    // route callback be fired (not usually desirable), or `replace: true`, if
    // you wish to modify the current URL without adding an entry to the history.
    navigate: function(fragment, options) {
      if (!History.started) return false;
      if (!options || options === true) options = {trigger: options};
      var frag = (fragment || '').replace(routeStripper, '');
      if (this.fragment == frag) return;

      // If pushState is available, we use it to set the fragment as a real URL.
      if (this._hasPushState) {
        if (frag.indexOf(this.options.root) != 0) frag = this.options.root + frag;
        this.fragment = frag;
        window.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, frag);

      // If hash changes haven't been explicitly disabled, update the hash
      // fragment to store history.
      } else if (this._wantsHashChange) {
        this.fragment = frag;
        this._updateHash(window.location, frag, options.replace);
        if (this.iframe && (frag != this.getFragment(this.getHash(this.iframe)))) {
          // Opening and closing the iframe tricks IE7 and earlier to push a history entry on hash-tag change.
          // When replace is true, we don't want this.
          if(!options.replace) this.iframe.document.open().close();
          this._updateHash(this.iframe.location, frag, options.replace);
        }

      // If you've told us that you explicitly don't want fallback hashchange-
      // based history, then `navigate` becomes a page refresh.
      } else {
        window.location.assign(this.options.root + fragment);
      }
      if (options.trigger) this.loadUrl(fragment);
    },

    // Update the hash location, either replacing the current entry, or adding
    // a new one to the browser history.
    _updateHash: function(location, fragment, replace) {
      if (replace) {
        location.replace(location.toString().replace(/(javascript:|#).*$/, '') + '#' + fragment);
      } else {
        location.hash = fragment;
      }
    }
  });

  // Backbone.View
  // -------------

  // Creating a Backbone.View creates its initial element outside of the DOM,
  // if an existing element is not provided...
  var View = Backbone.View = function(options) {
    this.cid = _.uniqueId('view');
    this._configure(options || {});
    this._ensureElement();
    this.initialize.apply(this, arguments);
    this.delegateEvents();
  };

  // Cached regex to split keys for `delegate`.
  var delegateEventSplitter = /^(\S+)\s*(.*)$/;

  // List of view options to be merged as properties.
  var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName'];

  // Set up all inheritable **Backbone.View** properties and methods.
  _.extend(View.prototype, Events, {

    // The default `tagName` of a View's element is `"div"`.
    tagName: 'div',

    // jQuery delegate for element lookup, scoped to DOM elements within the
    // current view. This should be prefered to global lookups where possible.
    $: function(selector) {
      return this.$el.find(selector);
    },

    // Initialize is an empty function by default. Override it with your own
    // initialization logic.
    initialize: function(){},

    // **render** is the core function that your view should override, in order
    // to populate its element (`this.el`), with the appropriate HTML. The
    // convention is for **render** to always return `this`.
    render: function() {
      return this;
    },

    // Remove this view from the DOM. Note that the view isn't present in the
    // DOM by default, so calling this method may be a no-op.
    remove: function() {
      this.$el.remove();
      return this;
    },

    // For small amounts of DOM Elements, where a full-blown template isn't
    // needed, use **make** to manufacture elements, one at a time.
    //
    //     var el = this.make('li', {'class': 'row'}, this.model.escape('title'));
    //
    make: function(tagName, attributes, content) {
      var el = document.createElement(tagName);
      if (attributes) $(el).attr(attributes);
      if (content) $(el).html(content);
      return el;
    },

    // Change the view's element (`this.el` property), including event
    // re-delegation.
    setElement: function(element, delegate) {
      if (this.$el) this.undelegateEvents();
      this.$el = (element instanceof $) ? element : $(element);
      this.el = this.$el[0];
      if (delegate !== false) this.delegateEvents();
      return this;
    },

    // Set callbacks, where `this.events` is a hash of
    //
    // *{"event selector": "callback"}*
    //
    //     {
    //       'mousedown .title':  'edit',
    //       'click .button':     'save'
    //       'click .open':       function(e) { ... }
    //     }
    //
    // pairs. Callbacks will be bound to the view, with `this` set properly.
    // Uses event delegation for efficiency.
    // Omitting the selector binds the event to `this.el`.
    // This only works for delegate-able events: not `focus`, `blur`, and
    // not `change`, `submit`, and `reset` in Internet Explorer.
    delegateEvents: function(events) {
      if (!(events || (events = getValue(this, 'events')))) return;
      this.undelegateEvents();
      for (var key in events) {
        var method = events[key];
        if (!_.isFunction(method)) method = this[events[key]];
        if (!method) throw new Error('Method "' + events[key] + '" does not exist');
        var match = key.match(delegateEventSplitter);
        var eventName = match[1], selector = match[2];
        method = _.bind(method, this);
        eventName += '.delegateEvents' + this.cid;
        if (selector === '') {
          this.$el.bind(eventName, method);
        } else {
          this.$el.delegate(selector, eventName, method);
        }
      }
    },

    // Clears all callbacks previously bound to the view with `delegateEvents`.
    // You usually don't need to use this, but may wish to if you have multiple
    // Backbone views attached to the same DOM element.
    undelegateEvents: function() {
      this.$el.unbind('.delegateEvents' + this.cid);
    },

    // Performs the initial configuration of a View with a set of options.
    // Keys with special meaning *(model, collection, id, className)*, are
    // attached directly to the view.
    _configure: function(options) {
      if (this.options) options = _.extend({}, this.options, options);
      for (var i = 0, l = viewOptions.length; i < l; i++) {
        var attr = viewOptions[i];
        if (options[attr]) this[attr] = options[attr];
      }
      this.options = options;
    },

    // Ensure that the View has a DOM element to render into.
    // If `this.el` is a string, pass it through `$()`, take the first
    // matching element, and re-assign it to `el`. Otherwise, create
    // an element from the `id`, `className` and `tagName` properties.
    _ensureElement: function() {
      if (!this.el) {
        var attrs = getValue(this, 'attributes') || {};
        if (this.id) attrs.id = this.id;
        if (this.className) attrs['class'] = this.className;
        this.setElement(this.make(this.tagName, attrs), false);
      } else {
        this.setElement(this.el, false);
      }
    }

  });

  // The self-propagating extend function that Backbone classes use.
  var extend = function (protoProps, classProps) {
    var child = inherits(this, protoProps, classProps);
    child.extend = this.extend;
    return child;
  };

  // Set up inheritance for the model, collection, and view.
  Model.extend = Collection.extend = Router.extend = View.extend = extend;

  // Backbone.sync
  // -------------

  // Map from CRUD to HTTP for our default `Backbone.sync` implementation.
  var methodMap = {
    'create': 'POST',

    // huy@coursera 2012-04-13 For our specs we use PATCH
    //'update': 'PUT',
    'update': 'PATCH',

    'delete': 'DELETE',
    'read':   'GET'
  };

  // Override this function to change the manner in which Backbone persists
  // models to the server. You will be passed the type of request, and the
  // model in question. By default, makes a RESTful Ajax request
  // to the model's `url()`. Some possible customizations could be:
  //
  // * Use `setTimeout` to batch rapid-fire updates into a single request.
  // * Send up the models as XML instead of JSON.
  // * Persist models via WebSockets instead of Ajax.
  //
  // Turn on `Backbone.emulateHTTP` in order to send `PUT` and `DELETE` requests
  // as `POST`, with a `_method` parameter containing the true HTTP method,
  // as well as all requests with the body as `application/x-www-form-urlencoded`
  // instead of `application/json` with the model in a param named `model`.
  // Useful when interfacing with server-side languages like **PHP** that make
  // it difficult to read the body of `PUT` requests.
  Backbone.sync = function(method, model, options) {
    var type = methodMap[method];

    // Default options, unless specified.
    options || (options = {});

    // Default JSON-request options.
    var params = {type: type, dataType: 'json'};

    // Ensure that we have a URL.
    if (!options.url) {
      params.url = getValue(model, 'url') || urlError();
    }

    // Ensure that we have the appropriate request data.
    if (!options.data && model && (method == 'create' || method == 'update')) {
      params.contentType = 'application/json';
      params.data = JSON.stringify(model.toJSON());
    }

    // For older servers, emulate JSON by encoding the request into an HTML-form.
    if (Backbone.emulateJSON) {
      params.contentType = 'application/x-www-form-urlencoded';
      params.data = params.data ? {model: params.data} : {};
    }

    // For older servers, emulate HTTP by mimicking the HTTP method with `_method`
    // And an `X-HTTP-Method-Override` header.
    if (Backbone.emulateHTTP) {
      // huy@coursera 2012-04-15 Add support for PATCH
      //if (type === 'PUT' || type === 'DELETE') {
      if (type === 'PATCH' || type === 'PUT' || type === 'DELETE') {
        if (Backbone.emulateJSON) params.data._method = type;
        params.type = 'POST';
        params.beforeSend = function(xhr) {
          xhr.setRequestHeader('X-HTTP-Method-Override', type);
        };
      }
    }

    // Don't process data on a non-GET request.
    if (params.type !== 'GET' && !Backbone.emulateJSON) {
      params.processData = false;
    }

    // Make the request, allowing the user to override any Ajax options.
    return $.ajax(_.extend(params, options));
  };

  // Wrap an optional error callback with a fallback error event.
  Backbone.wrapError = function(onError, originalModel, options) {
    return function(model, resp) {
      resp = model === originalModel ? resp : model;
      if (onError) {
        onError(originalModel, resp, options);
      } else {
        originalModel.trigger('error', originalModel, resp, options);
      }
    };
  };

  // Helpers
  // -------

  // Shared empty constructor function to aid in prototype-chain creation.
  var ctor = function(){};

  // Helper function to correctly set up the prototype chain, for subclasses.
  // Similar to `goog.inherits`, but uses a hash of prototype properties and
  // class properties to be extended.
  var inherits = function(parent, protoProps, staticProps) {
    var child;

    // The constructor function for the new subclass is either defined by you
    // (the "constructor" property in your `extend` definition), or defaulted
    // by us to simply call the parent's constructor.
    if (protoProps && protoProps.hasOwnProperty('constructor')) {
      child = protoProps.constructor;
    } else {
      child = function(){ parent.apply(this, arguments); };
    }

    // Inherit class (static) properties from parent.
    _.extend(child, parent);

    // Set the prototype chain to inherit from `parent`, without calling
    // `parent`'s constructor function.
    ctor.prototype = parent.prototype;
    child.prototype = new ctor();

    // Add prototype properties (instance properties) to the subclass,
    // if supplied.
    if (protoProps) _.extend(child.prototype, protoProps);

    // Add static properties to the constructor function, if supplied.
    if (staticProps) _.extend(child, staticProps);

    // Correctly set child's `prototype.constructor`.
    child.prototype.constructor = child;

    // Set a convenience property in case the parent's prototype is needed later.
    child.__super__ = parent.prototype;

    return child;
  };

  // Helper function to get a value from a Backbone object as a property
  // or as a function.
  var getValue = function(object, prop) {
    if (!(object && object[prop])) return null;
    return _.isFunction(object[prop]) ? object[prop]() : object[prop];
  };

  // Throw an error when a URL is needed, and none is supplied.
  var urlError = function() {
    throw new Error('A "url" property or function must be specified');
  };

}).call(this);

define("backbone", ["jquery","underscore"], (function (global) {
    return function () {
        var ret, fn;
        return ret || global.Backbone;
    };
}(this)));

/**
 * Improves Backbone Model support when nested attributes are used.
 * get() and set() can take paths e.g. 'user.name'
 */
;(function(Backbone) {

    /**
     * Takes a nested object and returns a shallow object keyed with the path names
     * e.g. { "level1.level2": "value" }
     *
     * @param  {Object}      Nested object e.g. { level1: { level2: 'value' } }
     * @return {Object}      Shallow object with path names e.g. { 'level1.level2': 'value' }
     */
    function objToPaths(obj) {
        var ret = {},
            separator = DeepModel.keyPathSeparator;

        for (var key in obj) {
            var val = obj[key];

            if (val && val.constructor === Object && !_.isEmpty(val)) {
                //Recursion for embedded objects
                var obj2 = objToPaths(val);

                for (var key2 in obj2) {
                    var val2 = obj2[key2];

                    ret[key + separator + key2] = val2;
                }
            } else {
                ret[key] = val;
            }
        }

        return ret;
    }

    /**
     * @param {Object}  Object to fetch attribute from
     * @param {String}  Object path e.g. 'user.name'
     * @return {Mixed}
     */
    function getNested(obj, path, return_exists) {
        var separator = DeepModel.keyPathSeparator;

        var fields = path.split(separator);
        var result = obj;
        return_exists || (return_exists = false)
        for (var i = 0, n = fields.length; i < n; i++) {
            if (return_exists
                && !_.has(result, fields[i]))
            {
                return false
            }
            result = result[fields[i]];

            if (result == null && i < n - 1) {
                result = {};
            }
            
            if (typeof result === 'undefined') {
                if (return_exists)
                {
                    return true;
                }
                return result;
            }
        }
        if (return_exists)
        {
            return true;
        }
        return result;
    }

    /**
     * @param {Object} obj                Object to fetch attribute from
     * @param {String} path               Object path e.g. 'user.name'
     * @param {Object} [options]          Options
     * @param {Boolean} [options.unset]   Whether to delete the value
     * @param {Mixed}                     Value to set
     */
    function setNested(obj, path, val, options) {
        options = options || {};

        var separator = DeepModel.keyPathSeparator;

        var fields = path.split(separator);
        var result = obj;
        for (var i = 0, n = fields.length; i < n; i++) {
            var field = fields[i];

            //If the last in the path, set the value
            if (i === n - 1) {
                options.unset ? delete result[field] : result[field] = val;
            } else {
                //Create the child object if it doesn't exist, or isn't an object
                if (typeof result[field] === 'undefined' || ! _.isObject(result[field])) {
                    result[field] = {};
                }

                //Move onto the next part of the path
                result = result[field];
            }
        }
    }

    function deleteNested(obj, path) {
      setNested(obj, path, null, { unset: true });
    }

    var DeepModel = Backbone.Model.extend({

        // Override get
        // Supports nested attributes via the syntax 'obj.attr' e.g. 'author.user.name'
        get: function(attr) {
            return getNested(this.attributes, attr);
        },

        // Override set
        // Supports nested attributes via the syntax 'obj.attr' e.g. 'author.user.name'
        set: function(key, value, options) {
            //<custom code>
            var Model = Backbone.Model;
            //</custom code>

            var attrs, attr, val;

            // Handle both `"key", value` and `{key: value}` -style arguments.
            if (_.isObject(key) || key == null) {
                attrs = key;
                options = value;
            } else {
                attrs = {};
                attrs[key] = value;
            }

            // Extract attributes and options.
            options || (options = {});
            if (!attrs) return this;
            if (attrs instanceof Model) attrs = attrs.attributes;
            if (options.unset) for (attr in attrs) attrs[attr] = void 0;

            // Run validation.
            if (!this._validate(attrs, options)) return false;

            // Check for changes of `id`.
            if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];

            var changes = options.changes = {};
            var now = this.attributes;
            var escaped = this._escapedAttributes;
            var prev = this._previousAttributes || {};


            // <custom code>
            attrs = objToPaths(attrs);

            // For each `set` attribute...
            for (attr in attrs) {
              val = attrs[attr];

              var currentValue = getNested(now, attr),
                  previousValue = getNested(prev, attr),
                  escapedValue = getNested(escaped, attr),
                  hasCurrentValue = _.isUndefined(currentValue),
                  hasPreviousValue = _.isUndefined(previousValue);

              // If the new and current value differ, record the change.
              if (!_.isEqual(currentValue, val) || (options.unset && hasCurrentValue)) {
                deleteNested(escaped, attr);
                setNested((options.silent ? this._silent : changes), attr, true);
              }

              // Update or delete the current value.
              options.unset ? deleteNested(now, attr) : setNested(now, attr, val);

              // If the new and previous value differ, record the change.  If not,
              // then remove changes for this attribute.
              if (!_.isEqual(previousValue, val) || (hasCurrentValue != hasPreviousValue)) {
                setNested(this.changed, attr, _.clone(val));
                if (!options.silent) setNested(this._pending, attr, true);
              } else {
                deleteNested(this.changed, attr);
                deleteNested(this._pending, attr);
              }
            }

            // Fire the `"change"` events.
            if (!options.silent) this.change(options);
            return this;
        },

        // Override has
        has: function(attr) {
            return getNested(this.attributes, attr) != null;
        },

        // Override change
        change: function(options) {
          options || (options = {});
          var changing = this._changing;
          this._changing = true;

          // Silent changes become pending changes.
          for (var attr in objToPaths(this._silent)) setNested(this._pending, attr, true);

          // Silent changes are triggered.
          var changes = _.extend({}, options.changes, this._silent);
          this._silent = {};
          for (var attr in objToPaths(changes)) {
            this.trigger('change:' + attr, this, this.get(attr), options);
          }
          if (changing) return this;

          // Continue firing `"change"` events while there are pending changes.
          while (!_.isEmpty(this._pending)) {
            this._pending = {};
            this.trigger('change', this, options);
            // Pending and silent changes still remain.
            for (var attr in objToPaths(this.changed)) {
              if (getNested(this._pending, attr) || getNested(this._silent, attr)) continue;
              deleteNested(this.change, attr);
            }
            this._previousAttributes = _.clone(this.attributes);
          }

          this._changing = false;
          return this;
        },

        changedAttributes: function(diff) {
          if (!diff) return this.hasChanged() ? _.clone(objToPaths(this.changed)) : false;
          var val, changed = false, old = this._previousAttributes;
          for (var attr in diff) {
            if (_.isEqual(old[attr], (val = diff[attr]))) continue;
            (changed || (changed = {}))[attr] = val;
          }
          return changed;
        },

    });


    //Config; override in your app to customise
    DeepModel.keyPathSeparator = '.';


    //Exports
    Backbone.DeepModel = DeepModel;

    //For use in NodeJS
    if (typeof module != 'undefined') module.exports = DeepModel;

})(Backbone);

define("deepmodel", ["backbone"], (function (global) {
    return function () {
        var ret, fn;
        return ret || global.Backbone.DeepModel;
    };
}(this)));

// Backbone.Marionette v0.7.0
//
// Copyright (C)2011 Derick Bailey, Muted Solutions, LLC
// Distributed Under MIT License
//
// Documentation and Full License Available at:
// http://github.com/derickbailey/backbone.marionette
Backbone.Marionette = (function(Backbone, _, $){
  var Marionette = {};

  Marionette.version = "0.7.0";

  // Marionette.View
  // ---------------

  // The core view type that other Marionette views extend from.
  Marionette.View = Backbone.View.extend({
    // Get the template or template id/selector for this view
    // instance. You can set a `template` attribute in the view
    // definition or pass a `template: "whatever"` parameter in
    // to the constructor options. The `template` can also be
    // a function that returns a selector string.
    getTemplateSelector: function(){
      var template;

      // Get the template from `this.options.template` or
      // `this.template`. The `options` takes precedence.
      if (this.options && this.options.template){
        template = this.options.template;
      } else {
        template = this.template;
      }

      // check if it's a function and execute it, if it is
      if (_.isFunction(template)){
        template  = template.call(this);
      }

      return template;
    },

    // Default `close` implementation, for removing a view from the
    // DOM and unbinding it. Regions will call this method
    // for you. You can specify an `onClose` method in your view to
    // add custom code that is called after the view is closed.
    close: function(){
      this.beforeClose && this.beforeClose();

      this.unbindAll();
      this.remove();

      this.onClose && this.onClose();
      this.trigger('close');
      this.unbind();

      /* huy 2012-04-12 Unbind events from ModelBinding.
       * See https://github.com/derickbailey/backbone.modelbinding
       */
      if (Backbone.ModelBinding)
        Backbone.ModelBinding.unbind(this);
    }
  });

  // Item View
  // ---------
  
  // A single item view implementation that contains code for rendering
  // with underscore.js templates, serializing the view's model or collection,
  // and calling several methods on extended views, such as `onRender`.
  Marionette.ItemView = Marionette.View.extend({
    constructor: function(){
      var args = slice.call(arguments);
      Marionette.View.prototype.constructor.apply(this, args);

      _.bindAll(this, "render");

      this.initialEvents();
    },

    // Configured the initial events that the item view 
    // binds to. Override this method to prevent the initial
    // events, or to add your own initial events.
    initialEvents: function(){
      if (this.collection){
        this.bindTo(this.collection, "reset", this.render, this);
      }
    },

    // Serialize the model or collection for the view. If a model is
    // found, `.toJSON()` is called. If a collection is found, `.toJSON()`
    // is also called, but is used to populate an `items` array in the
    // resulting data. If both are found, defaults to the model. 
    // You can override the `serializeData` method in your own view 
    // definition, to provide custom serialization for your view's data.
    serializeData: function(){
      var data;

      if (this.model) { data = this.model.toJSON(); }
      else if (this.collection) {
        data = { items: this.collection.toJSON() };
      }

      return data;
    },

    // Render the view, defaulting to underscore.js templates.
    // You can override this in your view definition.
    render: function(){
      var that = this;

      var deferredRender = $.Deferred();
      var template = this.getTemplateSelector();
      var deferredData = this.serializeData();

      this.beforeRender && this.beforeRender();
      this.trigger("item:before:render", that);

      $.when(deferredData).then(function(data) {
        var asyncRender = Marionette.Renderer.render(template, data);
        $.when(asyncRender).then(function(html){
          that.$el.html(html);
          that.onRender && that.onRender();
          that.trigger("item:rendered", that);
          that.trigger("render", that);
          deferredRender.resolve();
        });
      });

      return deferredRender.promise();
    },

    // Override the default close event to add a few
    // more events that are triggered.
    close: function(){
      this.trigger('item:before:close');
      Marionette.View.prototype.close.apply(this, arguments);
      this.trigger('item:closed');
    }
  });

  // Collection View
  // ---------------

  // A view that iterates over a Backbone.Collection
  // and renders an individual ItemView for each model.
  Marionette.CollectionView = Marionette.View.extend({
    constructor: function(){
      Marionette.View.prototype.constructor.apply(this, arguments);

      _.bindAll(this, "addItemView", "render");
      this.initialEvents();
    },

    // Configured the initial events that the collection view 
    // binds to. Override this method to prevent the initial
    // events, or to add your own initial events.
    initialEvents: function(){
      if (this.collection){
        this.bindTo(this.collection, "add", this.addChildView, this);
        this.bindTo(this.collection, "remove", this.removeItemView, this);
        this.bindTo(this.collection, "reset", this.render, this);
      }
    },

    // Handle a child item added to the collection
    addChildView: function(item){
      var ItemView = this.getItemView();
      return this.addItemView(item, ItemView);
    },

    // Loop through all of the items and render 
    // each of them with the specified `itemView`.
    render: function(){
      var that = this;
      var deferredRender = $.Deferred();
      var promises = [];
      var ItemView = this.getItemView();

      this.beforeRender && this.beforeRender();
      this.trigger("collection:before:render", this);

      this.closeChildren();
      this.collection && this.collection.each(function(item){
        var promise = that.addItemView(item, ItemView);
        promises.push(promise);
      });

      deferredRender.done(function(){
        this.onRender && this.onRender();
        this.trigger("collection:rendered", this);
      });

      $.when(promises).then(function(){
        deferredRender.resolveWith(that);
      });

      return deferredRender.promise();
    },

    // Retrieve the itemView type, either from `this.options.itemView`
    // or from the `itemView` in the object definition. The "options"
    // takes precedence.
    getItemView: function(){
      var itemView = this.options.itemView || this.itemView;

      if (!itemView){
        var err = new Error("An `itemView` must be specified");
        err.name = "NoItemViewError";
        throw err;
      }

      return itemView;
    },

    // Render the child item's view and add it to the
    // HTML for the collection view.
    addItemView: function(item, ItemView){
      var that = this;

      var view = this.buildItemView(item, ItemView);
      this.storeChild(view);
      this.trigger("item:added", view);

      var viewRendered = view.render();
      $.when(viewRendered).then(function(){
        that.appendHtml(that, view);
      });
      
      return viewRendered;
    },

    // Build an `itemView` for every model in the collection. 
    buildItemView: function(item, ItemView){
      var view = new ItemView({
        model: item
      });
      return view;
    },

    // Remove the child view and close it
    removeItemView: function(item){
      var view = this.children[item.cid];
      if (view){
        view.close();
        delete this.children[item.cid];
      }
      this.trigger("item:removed", view);
    },

    // Append the HTML to the collection's `el`.
    // Override this method to do something other
    // then `.append`.
    appendHtml: function(collectionView, itemView){
      collectionView.$el.append(itemView.el);
    },

    // Store references to all of the child `itemView`
    // instances so they can be managed and cleaned up, later.
    storeChild: function(view){
      if (!this.children){
        this.children = {};
      }
      this.children[view.model.cid] = view;
    },
    
    // Handle cleanup and other closing needs for
    // the collection of views.
    close: function(){
      this.trigger("collection:before:close");
      this.closeChildren();
      Marionette.View.prototype.close.apply(this, arguments);
      this.trigger("collection:closed");
    },

    closeChildren: function(){
      if (this.children){
        _.each(this.children, function(childView){
          childView.close();
        });
      }
    }
  });

  // Composite View
  // --------------

  // Used for rendering a branch-leaf, hierarchical structure.
  // Extends directly from CollectionView and also renders an
  // an item view as `modelView`, for the top leaf
  Marionette.CompositeView = Marionette.CollectionView.extend({
    constructor: function(options){
      Marionette.CollectionView.apply(this, arguments);
      this.itemView = this.getItemView();
    },

    // Retrieve the `itemView` to be used when rendering each of
    // the items in the collection. The default is to return
    // `this.itemView` or Marionette.CompositeView if no `itemView`
    // has been defined
    getItemView: function(){
      return this.itemView || this.constructor;
    },

    // Renders the model once, and the collection once. Calling
    // this again will tell the model's view to re-render itself
    // but the collection will not re-render.
    render: function(){
      var that = this;
      var compositeRendered = $.Deferred();

      var modelIsRendered = this.renderModel();
      $.when(modelIsRendered).then(function(html){
        that.$el.html(html);
        that.trigger("composite:model:rendered");
        that.trigger("render");

        var collectionIsRendered = that.renderCollection();
        $.when(collectionIsRendered).then(function(){
          compositeRendered.resolve();
        });
      });

      compositeRendered.done(function(){
        that.trigger("composite:rendered");
      });

      return compositeRendered.promise();
    },

    // Render the collection for the composite view
    renderCollection: function(){
      var collectionDeferred = Marionette.CollectionView.prototype.render.apply(this, arguments);
      collectionDeferred.done(function(){
        this.trigger("composite:collection:rendered");
      });
      return collectionDeferred.promise();
    },

    // Render an individual model, if we have one, as
    // part of a composite view (branch / leaf). For example:
    // a treeview.
    renderModel: function(){
      var data = {};
      if (this.model){
        data = this.model.toJSON();
      }

      var template = this.getTemplateSelector();
      return Marionette.Renderer.render(template, data);
    }
  });

  // Region 
  // ------

  // Manage the visual regions of your composite application. See
  // http://lostechies.com/derickbailey/2011/12/12/composite-js-apps-regions-and-region-managers/
  Marionette.Region = function(options){
    this.options = options || {};

    _.extend(this, options);

    if (!this.el){
      var err = new Error("An 'el' must be specified");
      err.name = "NoElError";
      throw err;
    }
  };

  _.extend(Marionette.Region.prototype, Backbone.Events, {

    // Displays a backbone view instance inside of the region.
    // Handles calling the `render` method for you. Reads content
    // directly from the `el` attribute. Also calls an optional
    // `onShow` and `close` method on your view, just after showing
    // or just before closing the view, respectively.
    show: function(view, appendMethod){
      this.ensureEl();

      this.close();
      this.open(view, appendMethod);

      this.currentView = view;
    },

    ensureEl: function(){
      if (!this.$el || this.$el.length == 0){
        this.$el = this.getEl(this.el);
      }
    },

    // Override this method to change how the region finds the
    // DOM element that it manages. Return a jQuery selector object.
    getEl: function(selector){
        return $(selector);
    },

    // Internal method to render and display a view. Not meant 
    // to be called from any external code.
    open: function(view, appendMethod){
      var that = this;
      appendMethod = appendMethod || "html";

      $.when(view.render()).then(function () {
        that.$el[appendMethod](view.el);
        view.onShow && view.onShow();
        view.trigger("show");
        that.trigger("view:show", view);
      });
    },

    // Close the current view, if there is one. If there is no
    // current view, it does nothing and returns immediately.
    close: function(){
      var view = this.currentView;
      if (!view){ return; }

      view.close && view.close();
      this.trigger("view:closed", view);

      delete this.currentView;
    },

    // Attach an existing view to the region. This 
    // will not call `render` or `onShow` for the new view, 
    // and will not replace the current HTML for the `el`
    // of the region.
    attachView: function(view){
      this.currentView = view;
    }
  });

  // Layout
  // ------

  // Formerly known as Composite Region.
  //
  // Used for managing application layouts, nested layouts and
  // multiple regions within an application or sub-application.
  //
  // A specialized view type that renders an area of HTML and then
  // attaches `Region` instances to the specified `regions`.
  // Used for composite view management and sub-application areas.
  Marionette.Layout = Marionette.ItemView.extend({
    constructor: function () {
      this.vent = new Backbone.Marionette.EventAggregator();
      Backbone.Marionette.ItemView.apply(this, arguments);
      this.regionManagers = {};
    },

    render: function () {
      this.initializeRegions();
      return Backbone.Marionette.ItemView.prototype.render.call(this, arguments);
    },

    close: function () {
      this.closeRegions();
      Backbone.Marionette.ItemView.prototype.close.call(this, arguments);
    },

    initializeRegions: function () {
      var that = this;
      _.each(this.regions, function (selector, name) {
        var regionManager = new Backbone.Marionette.Region({
            el: selector,

            getEl: function(selector){
              return that.$(selector);
            }
        });
        that.regionManagers[name] = regionManager;
        that[name] = regionManager;
      });
    },

    closeRegions: function () {
      var that = this;
      _.each(this.regionManagers, function (manager, name) {
        manager.close();
        delete that[name];
      });
      this.regionManagers = {};
    }
  });

  // AppRouter
  // ---------

  // Reduce the boilerplate code of handling route events
  // and then calling a single method on another object.
  // Have your routers configured to call the method on
  // your object, directly.
  //
  // Configure an AppRouter with `appRoutes`.
  //
  // App routers can only take one `controller` object. 
  // It is reocmmended that you divide your controller
  // objects in to smaller peices of related functionality
  // and have multiple routers / controllers, instead of
  // just one giant router and controller.
  //
  // You can also add standard routes to an AppRouter.
  
  Marionette.AppRouter = Backbone.Router.extend({

    constructor: function(options){
      Backbone.Router.prototype.constructor.call(this, options);

      if (this.appRoutes){
        var controller = this.controller;
        if (options && options.controller) {
          controller = options.controller;
        }
        this.processAppRoutes(controller, this.appRoutes);
      }
    },

    processAppRoutes: function(controller, appRoutes){
      var method, methodName;
      var route, routesLength;
      var routes = [];
      var router = this;

      for(route in appRoutes){
        routes.unshift([route, appRoutes[route]]);
      }

      routesLength = routes.length;
      for (var i = 0; i < routesLength; i++){
        route = routes[i][0];
        methodName = routes[i][1];
        method = _.bind(controller[methodName], controller);
        router.route(route, methodName, method);
      }
    }
  });
  
  // Composite Application
  // ---------------------

  // Contain and manage the composite application as a whole.
  // Stores and starts up `Region` objects, includes an
  // event aggregator as `app.vent`
  Marionette.Application = function(options){
    this.initCallbacks = new Marionette.Callbacks();
    this.vent = new Marionette.EventAggregator();
    _.extend(this, options);
  };

  _.extend(Marionette.Application.prototype, Backbone.Events, {
    // Add an initializer that is either run at when the `start`
    // method is called, or run immediately if added after `start`
    // has already been called.
    addInitializer: function(initializer){
      this.initCallbacks.add(initializer);
    },

    // kick off all of the application's processes.
    // initializes all of the regions that have been added
    // to the app, and runs all of the initializer functions
    start: function(options){
      this.trigger("initialize:before", options);
      this.initCallbacks.run(this, options);
      this.trigger("initialize:after", options);

      this.trigger("start", options);
    },

    // Add regions to your app. 
    // Accepts a hash of named strings or Region objects
    // addRegions({something: "#someRegion"})
    // addRegions{{something: Region.extend({el: "#someRegion"}) });
    addRegions: function(regions){
      var regionValue, regionObj;

      for(var region in regions){
        if (regions.hasOwnProperty(region)){
          regionValue = regions[region];
    
          if (typeof regionValue === "string"){
            regionObj = new Marionette.Region({
              el: regionValue
            });
          } else {
            regionObj = new regionValue;
          }

          this[region] = regionObj;
        }
      }
    }
  });

  // BindTo: Event Binding
  // ---------------------
  
  // BindTo facilitates the binding and unbinding of events
  // from objects that extend `Backbone.Events`. It makes
  // unbinding events, even with anonymous callback functions,
  // easy. 
  //
  // Thanks to Johnny Oshika for this code.
  // http://stackoverflow.com/questions/7567404/backbone-js-repopulate-or-recreate-the-view/7607853#7607853
  Marionette.BindTo = {
    // Store the event binding in array so it can be unbound
    // easily, at a later point in time.
    bindTo: function (obj, eventName, callback, context) {
      context = context || this;
      obj.on(eventName, callback, context);

      if (!this.bindings) this.bindings = [];

      this.bindings.push({ 
        obj: obj, 
        eventName: eventName, 
        callback: callback, 
        context: context 
      });
    },

    // Unbind all of the events that we have stored.
    unbindAll: function () {
      _.each(this.bindings, function (binding) {
        binding.obj.off(binding.eventName, binding.callback);
      });

      this.bindings = [];
    }
  };

  // Callbacks
  // ---------

  // A simple way of managing a collection of callbacks
  // and executing them at a later point in time, using jQuery's
  // `Deferred` object.
  Marionette.Callbacks = function(){
    this.deferred = $.Deferred();
    this.promise = this.deferred.promise();
  };

  _.extend(Marionette.Callbacks.prototype, {
    
    // Add a callback to be executed. Callbacks added here are
    // guaranteed to execute, even if they are added after the 
    // `run` method is called.
    add: function(callback){
      this.promise.done(function(context, options){
        callback.call(context, options);
      });
    },

    // Run all registered callbacks with the context specified. 
    // Additional callbacks can be added after this has been run 
    // and they will still be executed.
    run: function(context, options){
      this.deferred.resolve(context, options);
    }
  });

  // Event Aggregator
  // ----------------

  // A pub-sub object that can be used to decouple various parts
  // of an application through event-driven architecture.
  Marionette.EventAggregator = function(options){
    _.extend(this, options);
  };

  _.extend(Marionette.EventAggregator.prototype, Backbone.Events, Marionette.BindTo, {
    // Assumes the event aggregator itself is the 
    // object being bound to.
    bindTo: function(eventName, callback, context){
      Marionette.BindTo.bindTo.call(this, this, eventName, callback, context);
    }
  });

  // Template Cache
  // --------------
  
  // Manage templates stored in `<script>` blocks,
  // caching them for faster access.
  Marionette.TemplateCache = {
    templates: {},
    loaders: {},

    // Get the specified template by id. Either
    // retrieves the cached version, or loads it
    // from the DOM.
    get: function(templateId){
      var that = this;
      var templateRetrieval = $.Deferred();
      var cachedTemplate = this.templates[templateId];

      if (cachedTemplate){
        templateRetrieval.resolve(cachedTemplate);
      } else {
        var loader = this.loaders[templateId];
        if(loader) {
          templateRetrieval = loader;
        } else {
          this.loaders[templateId] = templateRetrieval;

          this.loadTemplate(templateId, function(template){
            delete that.loaders[templateId];
            that.templates[templateId] = template;
            templateRetrieval.resolve(template);
          });
        }

      }

      return templateRetrieval.promise();
    },

    // Load a template from the DOM, by default. Override
    // this method to provide your own template retrieval,
    // such as asynchronous loading from a server.
    loadTemplate: function(templateId, callback){
      var template = $(templateId).html();
      callback.call(this, template);
    },

    // Clear templates from the cache. If no arguments
    // are specified, clears all templates:
    // `clear()`
    //
    // If arguments are specified, clears each of the 
    // specified templates from the cache:
    // `clear("#t1", "#t2", "...")`
    clear: function(){
      var length = arguments.length;
      if (length > 0){
        for(var i=0; i<length; i++){
          delete this.templates[arguments[i]];
        }
      } else {
        this.templates = {};
      }
    }
  };

  // Renderer
  // --------
  
  // Render a template with data by passing in the template
  // selector and the data to render.
  Marionette.Renderer = {

    // Render a template with data. The `template` parameter is
    // passed to the `TemplateCache` object to retrieve the
    // actual template. Override this method to provide your own
    // custom rendering and template handling for all of Marionette.
    render: function(template, data){
      var that = this;
      var asyncRender = $.Deferred();

      var templateRetrieval = Marionette.TemplateCache.get(template);

      $.when(templateRetrieval).then(function(template){
        var html = that.renderTemplate(template, data);
        asyncRender.resolve(html);
      });

      return asyncRender.promise();
    },

    // Default implementation uses underscore.js templates. Override
    // this method to use your own templating engine.
    renderTemplate: function(template, data){
      if (!template || template.length === 0){
        var msg = "A template must be specified";
        var err = new Error(msg);
        err.name = "NoTemplateError";
        throw err;
      }

      var html = _.template(template, data);
      return html;
    }

  }

  // Helpers
  // -------

  // For slicing `arguments` in functions
  var slice = Array.prototype.slice;
  
  // Copy the `extend` function used by Backbone's classes
  var extend = Marionette.View.extend;
  Marionette.Region.extend = extend;
  Marionette.Application.extend = extend;

  // Copy the features of `BindTo` on to these objects
  _.extend(Marionette.View.prototype, Marionette.BindTo);
  _.extend(Marionette.Application.prototype, Marionette.BindTo);
  _.extend(Marionette.Region.prototype, Marionette.BindTo);

  return Marionette;
})(Backbone, _, window.jQuery || window.Zepto || window.ender);

;
define("marionette", ["backbone"], (function (global) {
    return function () {
        var ret, fn;
        return ret || global.Backbone.Marionette;
    };
}(this)));

/*
    http://www.JSON.org/json2.js
    2011-10-19

    Public Domain.

    NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.

    See http://www.JSON.org/js.html


    This code should be minified before deployment.
    See http://javascript.crockford.com/jsmin.html

    USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO
    NOT CONTROL.
*/

/*jslint evil: true, regexp: true */

/*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
    call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
    getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join,
    lastIndex, length, parse, prototype, push, replace, slice, stringify,
    test, toJSON, toString, valueOf
*/

(function (window){

// Create a JSON object only if one does not already exist. We create the
// methods in a closure to avoid creating global variables.

// Return the window JSON element if it exists;
var JSON = window.JSON || {};

(function () {
    

    function f(n) {
        // Format integers to have at least two digits.
        return n < 10 ? '0' + n : n;
    }

    if (typeof Date.prototype.toJSON !== 'function') {

        Date.prototype.toJSON = function (key) {

            return isFinite(this.valueOf())
                ? this.getUTCFullYear()     + '-' +
                    f(this.getUTCMonth() + 1) + '-' +
                    f(this.getUTCDate())      + 'T' +
                    f(this.getUTCHours())     + ':' +
                    f(this.getUTCMinutes())   + ':' +
                    f(this.getUTCSeconds())   + 'Z'
                : null;
        };

        String.prototype.toJSON      =
            Number.prototype.toJSON  =
            Boolean.prototype.toJSON = function (key) {
                return this.valueOf();
            };
    }

    var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,
        gap,
        indent,
        meta = {    // table of character substitutions
            '\b': '\\b',
            '\t': '\\t',
            '\n': '\\n',
            '\f': '\\f',
            '\r': '\\r',
            '"' : '\\"',
            '\\': '\\\\'
        },
        rep;


    function quote(string) {

// If the string contains no control characters, no quote characters, and no
// backslash characters, then we can safely slap some quotes around it.
// Otherwise we must also replace the offending characters with safe escape
// sequences.

        escapable.lastIndex = 0;
        return escapable.test(string) ? '"' + string.replace(escapable, function (a) {
            var c = meta[a];
            return typeof c === 'string'
                ? c
                : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
        }) + '"' : '"' + string + '"';
    }


    function str(key, holder) {

// Produce a string from holder[key].

        var i,          // The loop counter.
            k,          // The member key.
            v,          // The member value.
            length,
            mind = gap,
            partial,
            value = holder[key];

// If the value has a toJSON method, call it to obtain a replacement value.

        if (value && typeof value === 'object' &&
                typeof value.toJSON === 'function') {
            value = value.toJSON(key);
        }

// If we were called with a replacer function, then call the replacer to
// obtain a replacement value.

        if (typeof rep === 'function') {
            value = rep.call(holder, key, value);
        }

// What happens next depends on the value's type.

        switch (typeof value) {
        case 'string':
            return quote(value);

        case 'number':

// JSON numbers must be finite. Encode non-finite numbers as null.

            return isFinite(value) ? String(value) : 'null';

        case 'boolean':
        case 'null':

// If the value is a boolean or null, convert it to a string. Note:
// typeof null does not produce 'null'. The case is included here in
// the remote chance that this gets fixed someday.

            return String(value);

// If the type is 'object', we might be dealing with an object or an array or
// null.

        case 'object':

// Due to a specification blunder in ECMAScript, typeof null is 'object',
// so watch out for that case.

            if (!value) {
                return 'null';
            }

// Make an array to hold the partial results of stringifying this object value.

            gap += indent;
            partial = [];

// Is the value an array?

            if (Object.prototype.toString.apply(value) === '[object Array]') {

// The value is an array. Stringify every element. Use null as a placeholder
// for non-JSON values.

                length = value.length;
                for (i = 0; i < length; i += 1) {
                    partial[i] = str(i, value) || 'null';
                }

// Join all of the elements together, separated with commas, and wrap them in
// brackets.

                v = partial.length === 0
                    ? '[]'
                    : gap
                    ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']'
                    : '[' + partial.join(',') + ']';
                gap = mind;
                return v;
            }

// If the replacer is an array, use it to select the members to be stringified.

            if (rep && typeof rep === 'object') {
                length = rep.length;
                for (i = 0; i < length; i += 1) {
                    if (typeof rep[i] === 'string') {
                        k = rep[i];
                        v = str(k, value);
                        if (v) {
                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
                        }
                    }
                }
            } else {

// Otherwise, iterate through all of the keys in the object.

                for (k in value) {
                    if (Object.prototype.hasOwnProperty.call(value, k)) {
                        v = str(k, value);
                        if (v) {
                            partial.push(quote(k) + (gap ? ': ' : ':') + v);
                        }
                    }
                }
            }

// Join all of the member texts together, separated with commas,
// and wrap them in braces.

            v = partial.length === 0
                ? '{}'
                : gap
                ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}'
                : '{' + partial.join(',') + '}';
            gap = mind;
            return v;
        }
    }

// If the JSON object does not yet have a stringify method, give it one.

    if (typeof JSON.stringify !== 'function') {
        JSON.stringify = function (value, replacer, space) {

// The stringify method takes a value and an optional replacer, and an optional
// space parameter, and returns a JSON text. The replacer can be a function
// that can replace values, or an array of strings that will select the keys.
// A default replacer method can be provided. Use of the space parameter can
// produce text that is more easily readable.

            var i;
            gap = '';
            indent = '';

// If the space parameter is a number, make an indent string containing that
// many spaces.

            if (typeof space === 'number') {
                for (i = 0; i < space; i += 1) {
                    indent += ' ';
                }

// If the space parameter is a string, it will be used as the indent string.

            } else if (typeof space === 'string') {
                indent = space;
            }

// If there is a replacer, it must be a function or an array.
// Otherwise, throw an error.

            rep = replacer;
            if (replacer && typeof replacer !== 'function' &&
                    (typeof replacer !== 'object' ||
                    typeof replacer.length !== 'number')) {
                throw new Error('JSON.stringify');
            }

// Make a fake root object containing our value under the key of ''.
// Return the result of stringifying the value.

            return str('', {'': value});
        };
    }


// If the JSON object does not yet have a parse method, give it one.

    if (typeof JSON.parse !== 'function') {
        JSON.parse = function (text, reviver) {

// The parse method takes a text and an optional reviver function, and returns
// a JavaScript value if the text is a valid JSON text.

            var j;

            function walk(holder, key) {

// The walk method is used to recursively walk the resulting structure so
// that modifications can be made.

                var k, v, value = holder[key];
                if (value && typeof value === 'object') {
                    for (k in value) {
                        if (Object.prototype.hasOwnProperty.call(value, k)) {
                            v = walk(value, k);
                            if (v !== undefined) {
                                value[k] = v;
                            } else {
                                delete value[k];
                            }
                        }
                    }
                }
                return reviver.call(holder, key, value);
            }


// Parsing happens in four stages. In the first stage, we replace certain
// Unicode characters with escape sequences. JavaScript handles many characters
// incorrectly, either silently deleting them, or treating them as line endings.

            text = String(text);
            cx.lastIndex = 0;
            if (cx.test(text)) {
                text = text.replace(cx, function (a) {
                    return '\\u' +
                        ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
                });
            }

// In the second stage, we run the text against regular expressions that look
// for non-JSON patterns. We are especially concerned with '()' and 'new'
// because they can cause invocation, and '=' because it can cause mutation.
// But just to be safe, we want to reject all unexpected forms.

// We split the second stage into 4 regexp operations in order to work around
// crippling inefficiencies in IE's and Safari's regexp engines. First we
// replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
// replace all simple value tokens with ']' characters. Third, we delete all
// open brackets that follow a colon or comma or that begin the text. Finally,
// we look to see that the remaining characters are only whitespace or ']' or
// ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.

            if (/^[\],:{}\s]*$/
                    .test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')
                        .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']')
                        .replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {

// In the third stage we use the eval function to compile the text into a
// JavaScript structure. The '{' operator is subject to a syntactic ambiguity
// in JavaScript: it can begin a block or an object literal. We wrap the text
// in parens to eliminate the ambiguity.

                j = eval('(' + text + ')');

// In the optional fourth stage, we recursively walk the new structure, passing
// each name/value pair to a reviver function for possible transformation.

                return typeof reviver === 'function'
                    ? walk({'': j}, '')
                    : j;
            }

// If the text is not JSON parseable, then a SyntaxError is thrown.

            throw new SyntaxError('JSON.parse');
        };
    }
}());

define('json2',[],function(){
    return JSON;
});
// otherwise just leave it alone
    
}).call(this, this);
(function(){

// lib/handlebars/base.js
var Handlebars = {};

Handlebars.VERSION = "1.0.beta.4";

Handlebars.helpers  = {};
Handlebars.partials = {};

Handlebars.registerHelper = function(name, fn, inverse) {
  if(inverse) { fn.not = inverse; }
  this.helpers[name] = fn;
};

Handlebars.registerPartial = function(name, str) {
  this.partials[name] = str;
};

Handlebars.registerHelper('helperMissing', function(arg) {
  if(arguments.length === 2) {
    return undefined;
  } else {
    throw new Error("Could not find property '" + arg + "'");
  }
});

Handlebars.registerHelper('blockHelperMissing', function(context, options) {
  var inverse = options.inverse || function() {}, fn = options.fn;


  var ret = "";
  var type = Object.prototype.toString.call(context);

  if(type === "[object Function]") {
    context = context();
  }

  if(context === true) {
    return fn(this);
  } else if(context === false || context == null) {
    return inverse(this);
  } else if(type === "[object Array]") {
    if(context.length > 0) {
      for(var i=0, j=context.length; i<j; i++) {
        ret = ret + fn(context[i]);
      }
    } else {
      ret = inverse(this);
    }
    return ret;
  } else {
    return fn(context);
  }
});

Handlebars.registerHelper('each', function(context, options) {
  var fn = options.fn, inverse = options.inverse;
  var ret = "";

  if(context && context.length > 0) {
    for(var i=0, j=context.length; i<j; i++) {
      ret = ret + fn(context[i]);
    }
  } else {
    ret = inverse(this);
  }
  return ret;
});

Handlebars.registerHelper('if', function(context, options) {
  if(!context || Handlebars.Utils.isEmpty(context)) {
    return options.inverse(this);
  } else {
    return options.fn(this);
  }
});

Handlebars.registerHelper('unless', function(context, options) {
  var fn = options.fn, inverse = options.inverse;
  options.fn = inverse;
  options.inverse = fn;

  return Handlebars.helpers['if'].call(this, context, options);
});

Handlebars.registerHelper('with', function(context, options) {
  return options.fn(context);
});

Handlebars.registerHelper('log', function(context) {
  Handlebars.log(context);
});
;

// no need for parser if templates are pre-compiled

// lib/handlebars/compiler/parser.js
/* Jison generated parser */
var handlebars = (function(){

var parser = {trace: function trace() { },
yy: {},
symbols_: {"error":2,"root":3,"program":4,"EOF":5,"statements":6,"simpleInverse":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"inMustache":17,"CLOSE":18,"OPEN_INVERSE":19,"OPEN_ENDBLOCK":20,"path":21,"OPEN":22,"OPEN_UNESCAPED":23,"OPEN_PARTIAL":24,"params":25,"hash":26,"param":27,"STRING":28,"INTEGER":29,"BOOLEAN":30,"hashSegments":31,"hashSegment":32,"ID":33,"EQUALS":34,"pathSegments":35,"SEP":36,"$accept":0,"$end":1},
terminals_: {2:"error",5:"EOF",14:"CONTENT",15:"COMMENT",16:"OPEN_BLOCK",18:"CLOSE",19:"OPEN_INVERSE",20:"OPEN_ENDBLOCK",22:"OPEN",23:"OPEN_UNESCAPED",24:"OPEN_PARTIAL",28:"STRING",29:"INTEGER",30:"BOOLEAN",33:"ID",34:"EQUALS",36:"SEP"},
productions_: [0,[3,2],[4,3],[4,1],[4,0],[6,1],[6,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,3],[13,4],[7,2],[17,3],[17,2],[17,2],[17,1],[25,2],[25,1],[27,1],[27,1],[27,1],[27,1],[26,1],[31,2],[31,1],[32,3],[32,3],[32,3],[32,3],[21,1],[35,3],[35,1]],
performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {

var $0 = $$.length - 1;
switch (yystate) {
case 1: return $$[$0-1] 
break;
case 2: this.$ = new yy.ProgramNode($$[$0-2], $$[$0]) 
break;
case 3: this.$ = new yy.ProgramNode($$[$0]) 
break;
case 4: this.$ = new yy.ProgramNode([]) 
break;
case 5: this.$ = [$$[$0]] 
break;
case 6: $$[$0-1].push($$[$0]); this.$ = $$[$0-1] 
break;
case 7: this.$ = new yy.InverseNode($$[$0-2], $$[$0-1], $$[$0]) 
break;
case 8: this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0]) 
break;
case 9: this.$ = $$[$0] 
break;
case 10: this.$ = $$[$0] 
break;
case 11: this.$ = new yy.ContentNode($$[$0]) 
break;
case 12: this.$ = new yy.CommentNode($$[$0]) 
break;
case 13: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]) 
break;
case 14: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]) 
break;
case 15: this.$ = $$[$0-1] 
break;
case 16: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1]) 
break;
case 17: this.$ = new yy.MustacheNode($$[$0-1][0], $$[$0-1][1], true) 
break;
case 18: this.$ = new yy.PartialNode($$[$0-1]) 
break;
case 19: this.$ = new yy.PartialNode($$[$0-2], $$[$0-1]) 
break;
case 20: 
break;
case 21: this.$ = [[$$[$0-2]].concat($$[$0-1]), $$[$0]] 
break;
case 22: this.$ = [[$$[$0-1]].concat($$[$0]), null] 
break;
case 23: this.$ = [[$$[$0-1]], $$[$0]] 
break;
case 24: this.$ = [[$$[$0]], null] 
break;
case 25: $$[$0-1].push($$[$0]); this.$ = $$[$0-1]; 
break;
case 26: this.$ = [$$[$0]] 
break;
case 27: this.$ = $$[$0] 
break;
case 28: this.$ = new yy.StringNode($$[$0]) 
break;
case 29: this.$ = new yy.IntegerNode($$[$0]) 
break;
case 30: this.$ = new yy.BooleanNode($$[$0]) 
break;
case 31: this.$ = new yy.HashNode($$[$0]) 
break;
case 32: $$[$0-1].push($$[$0]); this.$ = $$[$0-1] 
break;
case 33: this.$ = [$$[$0]] 
break;
case 34: this.$ = [$$[$0-2], $$[$0]] 
break;
case 35: this.$ = [$$[$0-2], new yy.StringNode($$[$0])] 
break;
case 36: this.$ = [$$[$0-2], new yy.IntegerNode($$[$0])] 
break;
case 37: this.$ = [$$[$0-2], new yy.BooleanNode($$[$0])] 
break;
case 38: this.$ = new yy.IdNode($$[$0]) 
break;
case 39: $$[$0-2].push($$[$0]); this.$ = $$[$0-2]; 
break;
case 40: this.$ = [$$[$0]] 
break;
}
},
table: [{3:1,4:2,5:[2,4],6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],24:[1,15]},{1:[3]},{5:[1,16]},{5:[2,3],7:17,8:18,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,19],20:[2,3],22:[1,13],23:[1,14],24:[1,15]},{5:[2,5],14:[2,5],15:[2,5],16:[2,5],19:[2,5],20:[2,5],22:[2,5],23:[2,5],24:[2,5]},{4:20,6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],24:[1,15]},{4:21,6:3,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],24:[1,15]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],24:[2,9]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],24:[2,10]},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],24:[2,11]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],24:[2,12]},{17:22,21:23,33:[1,25],35:24},{17:26,21:23,33:[1,25],35:24},{17:27,21:23,33:[1,25],35:24},{17:28,21:23,33:[1,25],35:24},{21:29,33:[1,25],35:24},{1:[2,1]},{6:30,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],24:[1,15]},{5:[2,6],14:[2,6],15:[2,6],16:[2,6],19:[2,6],20:[2,6],22:[2,6],23:[2,6],24:[2,6]},{17:22,18:[1,31],21:23,33:[1,25],35:24},{10:32,20:[1,33]},{10:34,20:[1,33]},{18:[1,35]},{18:[2,24],21:40,25:36,26:37,27:38,28:[1,41],29:[1,42],30:[1,43],31:39,32:44,33:[1,45],35:24},{18:[2,38],28:[2,38],29:[2,38],30:[2,38],33:[2,38],36:[1,46]},{18:[2,40],28:[2,40],29:[2,40],30:[2,40],33:[2,40],36:[2,40]},{18:[1,47]},{18:[1,48]},{18:[1,49]},{18:[1,50],21:51,33:[1,25],35:24},{5:[2,2],8:18,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,2],22:[1,13],23:[1,14],24:[1,15]},{14:[2,20],15:[2,20],16:[2,20],19:[2,20],22:[2,20],23:[2,20],24:[2,20]},{5:[2,7],14:[2,7],15:[2,7],16:[2,7],19:[2,7],20:[2,7],22:[2,7],23:[2,7],24:[2,7]},{21:52,33:[1,25],35:24},{5:[2,8],14:[2,8],15:[2,8],16:[2,8],19:[2,8],20:[2,8],22:[2,8],23:[2,8],24:[2,8]},{14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],24:[2,14]},{18:[2,22],21:40,26:53,27:54,28:[1,41],29:[1,42],30:[1,43],31:39,32:44,33:[1,45],35:24},{18:[2,23]},{18:[2,26],28:[2,26],29:[2,26],30:[2,26],33:[2,26]},{18:[2,31],32:55,33:[1,56]},{18:[2,27],28:[2,27],29:[2,27],30:[2,27],33:[2,27]},{18:[2,28],28:[2,28],29:[2,28],30:[2,28],33:[2,28]},{18:[2,29],28:[2,29],29:[2,29],30:[2,29],33:[2,29]},{18:[2,30],28:[2,30],29:[2,30],30:[2,30],33:[2,30]},{18:[2,33],33:[2,33]},{18:[2,40],28:[2,40],29:[2,40],30:[2,40],33:[2,40],34:[1,57],36:[2,40]},{33:[1,58]},{14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],24:[2,13]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],24:[2,16]},{5:[2,17],14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],24:[2,17]},{5:[2,18],14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],24:[2,18]},{18:[1,59]},{18:[1,60]},{18:[2,21]},{18:[2,25],28:[2,25],29:[2,25],30:[2,25],33:[2,25]},{18:[2,32],33:[2,32]},{34:[1,57]},{21:61,28:[1,62],29:[1,63],30:[1,64],33:[1,25],35:24},{18:[2,39],28:[2,39],29:[2,39],30:[2,39],33:[2,39],36:[2,39]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],24:[2,19]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],24:[2,15]},{18:[2,34],33:[2,34]},{18:[2,35],33:[2,35]},{18:[2,36],33:[2,36]},{18:[2,37],33:[2,37]}],
defaultActions: {16:[2,1],37:[2,23],53:[2,21]},
parseError: function parseError(str, hash) {
    throw new Error(str);
},
parse: function parse(input) {
    var self = this,
        stack = [0],
        vstack = [null], // semantic value stack
        lstack = [], // location stack
        table = this.table,
        yytext = '',
        yylineno = 0,
        yyleng = 0,
        recovering = 0,
        TERROR = 2,
        EOF = 1;

    //this.reductionCount = this.shiftCount = 0;

    this.lexer.setInput(input);
    this.lexer.yy = this.yy;
    this.yy.lexer = this.lexer;
    if (typeof this.lexer.yylloc == 'undefined')
        this.lexer.yylloc = {};
    var yyloc = this.lexer.yylloc;
    lstack.push(yyloc);

    if (typeof this.yy.parseError === 'function')
        this.parseError = this.yy.parseError;

    function popStack (n) {
        stack.length = stack.length - 2*n;
        vstack.length = vstack.length - n;
        lstack.length = lstack.length - n;
    }

    function lex() {
        var token;
        token = self.lexer.lex() || 1; // $end = 1
        // if token isn't its numeric value, convert
        if (typeof token !== 'number') {
            token = self.symbols_[token] || token;
        }
        return token;
    };

    var symbol, preErrorSymbol, state, action, a, r, yyval={},p,len,newState, expected;
    while (true) {
        // retreive state number from top of stack
        state = stack[stack.length-1];

        // use default actions if available
        if (this.defaultActions[state]) {
            action = this.defaultActions[state];
        } else {
            if (symbol == null)
                symbol = lex();
            // read action for current state and first input
            action = table[state] && table[state][symbol];
        }

        // handle parse error
        if (typeof action === 'undefined' || !action.length || !action[0]) {

            if (!recovering) {
                // Report error
                expected = [];
                for (p in table[state]) if (this.terminals_[p] && p > 2) {
                    expected.push("'"+this.terminals_[p]+"'");
                }
                var errStr = '';
                if (this.lexer.showPosition) {
                    errStr = 'Parse error on line '+(yylineno+1)+":\n"+this.lexer.showPosition()+'\nExpecting '+expected.join(', ');
                } else {
                    errStr = 'Parse error on line '+(yylineno+1)+": Unexpected " +
                                  (symbol == 1 /*EOF*/ ? "end of input" :
                                              ("'"+(this.terminals_[symbol] || symbol)+"'"));
                }
                this.parseError(errStr,
                    {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
            }

            // just recovered from another error
            if (recovering == 3) {
                if (symbol == EOF) {
                    throw new Error(errStr || 'Parsing halted.');
                }

                // discard current lookahead and grab another
                yyleng = this.lexer.yyleng;
                yytext = this.lexer.yytext;
                yylineno = this.lexer.yylineno;
                yyloc = this.lexer.yylloc;
                symbol = lex();
            }

            // try to recover from error
            while (1) {
                // check for error recovery rule in this state
                if ((TERROR.toString()) in table[state]) {
                    break;
                }
                if (state == 0) {
                    throw new Error(errStr || 'Parsing halted.');
                }
                popStack(1);
                state = stack[stack.length-1];
            }

            preErrorSymbol = symbol; // save the lookahead token
            symbol = TERROR;         // insert generic error symbol as new lookahead
            state = stack[stack.length-1];
            action = table[state] && table[state][TERROR];
            recovering = 3; // allow 3 real symbols to be shifted before reporting a new error
        }

        // this shouldn't happen, unless resolve defaults are off
        if (action[0] instanceof Array && action.length > 1) {
            throw new Error('Parse Error: multiple actions possible at state: '+state+', token: '+symbol);
        }

        switch (action[0]) {

            case 1: // shift
                //this.shiftCount++;

                stack.push(symbol);
                vstack.push(this.lexer.yytext);
                lstack.push(this.lexer.yylloc);
                stack.push(action[1]); // push state
                symbol = null;
                if (!preErrorSymbol) { // normal execution/no error
                    yyleng = this.lexer.yyleng;
                    yytext = this.lexer.yytext;
                    yylineno = this.lexer.yylineno;
                    yyloc = this.lexer.yylloc;
                    if (recovering > 0)
                        recovering--;
                } else { // error just occurred, resume old lookahead f/ before error
                    symbol = preErrorSymbol;
                    preErrorSymbol = null;
                }
                break;

            case 2: // reduce
                //this.reductionCount++;

                len = this.productions_[action[1]][1];

                // perform semantic action
                yyval.$ = vstack[vstack.length-len]; // default to $$ = $1
                // default location, uses first token for firsts, last for lasts
                yyval._$ = {
                    first_line: lstack[lstack.length-(len||1)].first_line,
                    last_line: lstack[lstack.length-1].last_line,
                    first_column: lstack[lstack.length-(len||1)].first_column,
                    last_column: lstack[lstack.length-1].last_column
                };
                r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);

                if (typeof r !== 'undefined') {
                    return r;
                }

                // pop off stack
                if (len) {
                    stack = stack.slice(0,-1*len*2);
                    vstack = vstack.slice(0, -1*len);
                    lstack = lstack.slice(0, -1*len);
                }

                stack.push(this.productions_[action[1]][0]);    // push nonterminal (reduce)
                vstack.push(yyval.$);
                lstack.push(yyval._$);
                // goto new state = table[STATE][NONTERMINAL]
                newState = table[stack[stack.length-2]][stack[stack.length-1]];
                stack.push(newState);
                break;

            case 3: // accept
                return true;
        }

    }

    return true;
}};/* Jison generated lexer */
var lexer = (function(){

var lexer = ({EOF:1,
parseError:function parseError(str, hash) {
        if (this.yy.parseError) {
            this.yy.parseError(str, hash);
        } else {
            throw new Error(str);
        }
    },
setInput:function (input) {
        this._input = input;
        this._more = this._less = this.done = false;
        this.yylineno = this.yyleng = 0;
        this.yytext = this.matched = this.match = '';
        this.conditionStack = ['INITIAL'];
        this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
        return this;
    },
input:function () {
        var ch = this._input[0];
        this.yytext+=ch;
        this.yyleng++;
        this.match+=ch;
        this.matched+=ch;
        var lines = ch.match(/\n/);
        if (lines) this.yylineno++;
        this._input = this._input.slice(1);
        return ch;
    },
unput:function (ch) {
        this._input = ch + this._input;
        return this;
    },
more:function () {
        this._more = true;
        return this;
    },
pastInput:function () {
        var past = this.matched.substr(0, this.matched.length - this.match.length);
        return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
    },
upcomingInput:function () {
        var next = this.match;
        if (next.length < 20) {
            next += this._input.substr(0, 20-next.length);
        }
        return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
    },
showPosition:function () {
        var pre = this.pastInput();
        var c = new Array(pre.length + 1).join("-");
        return pre + this.upcomingInput() + "\n" + c+"^";
    },
next:function () {
        if (this.done) {
            return this.EOF;
        }
        if (!this._input) this.done = true;

        var token,
            match,
            col,
            lines;
        if (!this._more) {
            this.yytext = '';
            this.match = '';
        }
        var rules = this._currentRules();
        for (var i=0;i < rules.length; i++) {
            match = this._input.match(this.rules[rules[i]]);
            if (match) {
                lines = match[0].match(/\n.*/g);
                if (lines) this.yylineno += lines.length;
                this.yylloc = {first_line: this.yylloc.last_line,
                               last_line: this.yylineno+1,
                               first_column: this.yylloc.last_column,
                               last_column: lines ? lines[lines.length-1].length-1 : this.yylloc.last_column + match[0].length}
                this.yytext += match[0];
                this.match += match[0];
                this.matches = match;
                this.yyleng = this.yytext.length;
                this._more = false;
                this._input = this._input.slice(match[0].length);
                this.matched += match[0];
                token = this.performAction.call(this, this.yy, this, rules[i],this.conditionStack[this.conditionStack.length-1]);
                if (token) return token;
                else return;
            }
        }
        if (this._input === "") {
            return this.EOF;
        } else {
            this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(), 
                    {text: "", token: null, line: this.yylineno});
        }
    },
lex:function lex() {
        var r = this.next();
        if (typeof r !== 'undefined') {
            return r;
        } else {
            return this.lex();
        }
    },
begin:function begin(condition) {
        this.conditionStack.push(condition);
    },
popState:function popState() {
        return this.conditionStack.pop();
    },
_currentRules:function _currentRules() {
        return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
    }});
lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {

var YYSTATE=YY_START
switch($avoiding_name_collisions) {
case 0: this.begin("mu"); if (yy_.yytext) return 14; 
break;
case 1: return 14; 
break;
case 2: return 24; 
break;
case 3: return 16; 
break;
case 4: return 20; 
break;
case 5: return 19; 
break;
case 6: return 19; 
break;
case 7: return 23; 
break;
case 8: return 23; 
break;
case 9: yy_.yytext = yy_.yytext.substr(3,yy_.yyleng-5); this.begin("INITIAL"); return 15; 
break;
case 10: return 22; 
break;
case 11: return 34; 
break;
case 12: return 33; 
break;
case 13: return 33; 
break;
case 14: return 36; 
break;
case 15: /*ignore whitespace*/ 
break;
case 16: this.begin("INITIAL"); return 18; 
break;
case 17: this.begin("INITIAL"); return 18; 
break;
case 18: yy_.yytext = yy_.yytext.substr(1,yy_.yyleng-2).replace(/\\"/g,'"'); return 28; 
break;
case 19: return 30; 
break;
case 20: return 30; 
break;
case 21: return 29; 
break;
case 22: return 33; 
break;
case 23: yy_.yytext = yy_.yytext.substr(1, yy_.yyleng-2); return 33; 
break;
case 24: return 'INVALID'; 
break;
case 25: return 5; 
break;
}
};
lexer.rules = [/^[^\x00]*?(?=(\{\{))/,/^[^\x00]+/,/^\{\{>/,/^\{\{#/,/^\{\{\//,/^\{\{\^/,/^\{\{\s*else\b/,/^\{\{\{/,/^\{\{&/,/^\{\{![\s\S]*?\}\}/,/^\{\{/,/^=/,/^\.(?=[} ])/,/^\.\./,/^[/.]/,/^\s+/,/^\}\}\}/,/^\}\}/,/^"(\\["]|[^"])*"/,/^true(?=[}\s])/,/^false(?=[}\s])/,/^[0-9]+(?=[}\s])/,/^[a-zA-Z0-9_$-]+(?=[=}\s/.])/,/^\[.*\]/,/^./,/^$/];
lexer.conditions = {"mu":{"rules":[2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25],"inclusive":false},"INITIAL":{"rules":[0,1,25],"inclusive":true}};return lexer;})()
parser.lexer = lexer;
return parser;
})();
//CHANGE:: REMOVE AUTO EXPORTS
;
// lib/handlebars/compiler/base.js
Handlebars.Parser = handlebars;

Handlebars.parse = function(string) {
  Handlebars.Parser.yy = Handlebars.AST;
  return Handlebars.Parser.parse(string);
};


Handlebars.print = function(ast) {
  return new Handlebars.PrintVisitor().accept(ast);
};

Handlebars.logger = {
  DEBUG: 0, INFO: 1, WARN: 2, ERROR: 3, level: 3,

  // override in the host environment
  log: function(level, str) {}
};

Handlebars.log = function(level, str) { Handlebars.logger.log(level, str); };
;
// lib/handlebars/compiler/ast.js
(function() {

  Handlebars.AST = {};

  Handlebars.AST.ProgramNode = function(statements, inverse) {
    this.type = "program";
    this.statements = statements;
    if(inverse) { this.inverse = new Handlebars.AST.ProgramNode(inverse); }
  };

  Handlebars.AST.MustacheNode = function(params, hash, unescaped) {
    this.type = "mustache";
    this.id = params[0];
    this.params = params.slice(1);
    this.hash = hash;
    this.escaped = !unescaped;
  };

  Handlebars.AST.PartialNode = function(id, context) {
    this.type    = "partial";

    // TODO: disallow complex IDs

    this.id      = id;
    this.context = context;
  };

  var verifyMatch = function(open, close) {
    if(open.original !== close.original) {
      throw new Handlebars.Exception(open.original + " doesn't match " + close.original);
    }
  };

  Handlebars.AST.BlockNode = function(mustache, program, close) {
    verifyMatch(mustache.id, close);
    this.type = "block";
    this.mustache = mustache;
    this.program  = program;
  };

  Handlebars.AST.InverseNode = function(mustache, program, close) {
    verifyMatch(mustache.id, close);
    this.type = "inverse";
    this.mustache = mustache;
    this.program  = program;
  };

  Handlebars.AST.ContentNode = function(string) {
    this.type = "content";
    this.string = string;
  };

  Handlebars.AST.HashNode = function(pairs) {
    this.type = "hash";
    this.pairs = pairs;
  };

  Handlebars.AST.IdNode = function(parts) {
    this.type = "ID";
    this.original = parts.join(".");

    var dig = [], depth = 0;

    for(var i=0,l=parts.length; i<l; i++) {
      var part = parts[i];

      if(part === "..") { depth++; }
      else if(part === "." || part === "this") { this.isScoped = true; }
      else { dig.push(part); }
    }

    this.parts    = dig;
    this.string   = dig.join('.');
    this.depth    = depth;
    this.isSimple = (dig.length === 1) && (depth === 0);
  };

  Handlebars.AST.StringNode = function(string) {
    this.type = "STRING";
    this.string = string;
  };

  Handlebars.AST.IntegerNode = function(integer) {
    this.type = "INTEGER";
    this.integer = integer;
  };

  Handlebars.AST.BooleanNode = function(bool) {
    this.type = "BOOLEAN";
    this.bool = bool;
  };

  Handlebars.AST.CommentNode = function(comment) {
    this.type = "comment";
    this.comment = comment;
  };

})();;
// lib/handlebars/utils.js
Handlebars.Exception = function(message) {
  var tmp = Error.prototype.constructor.apply(this, arguments);

  for (var p in tmp) {
    if (tmp.hasOwnProperty(p)) { this[p] = tmp[p]; }
  }
};
Handlebars.Exception.prototype = new Error;

// Build out our basic SafeString type
Handlebars.SafeString = function(string) {
  this.string = string;
};
Handlebars.SafeString.prototype.toString = function() {
  return this.string.toString();
};

(function() {
  var escape = {
    "<": "&lt;",
    ">": "&gt;",
    '"': "&quot;",
    "'": "&#x27;",
    "`": "&#x60;"
  };

  var badChars = /&(?!\w+;)|[<>"'`]/g;
  var possible = /[&<>"'`]/;

  var escapeChar = function(chr) {
    return escape[chr] || "&amp;";
  };

  Handlebars.Utils = {
    escapeExpression: function(string) {
      // don't escape SafeStrings, since they're already safe
      if (string instanceof Handlebars.SafeString) {
        return string.toString();
      } else if (string == null || string === false) {
        return "";
      }

      if(!possible.test(string)) { return string; }
      return string.replace(badChars, escapeChar);
    },

    isEmpty: function(value) {
      if (typeof value === "undefined") {
        return true;
      } else if (value === null) {
        return true;
      } else if (value === false) {
        return true;
      } else if(Object.prototype.toString.call(value) === "[object Array]" && value.length === 0) {
        return true;
      } else {
        return false;
      }
    }
  };
})();;
// lib/handlebars/compiler/compiler.js
Handlebars.Compiler = function() {};
Handlebars.JavaScriptCompiler = function() {};

(function(Compiler, JavaScriptCompiler) {
  Compiler.OPCODE_MAP = {
    appendContent: 1,
    getContext: 2,
    lookupWithHelpers: 3,
    lookup: 4,
    append: 5,
    invokeMustache: 6,
    appendEscaped: 7,
    pushString: 8,
    truthyOrFallback: 9,
    functionOrFallback: 10,
    invokeProgram: 11,
    invokePartial: 12,
    push: 13,
    assignToHash: 15,
    pushStringParam: 16
  };

  Compiler.MULTI_PARAM_OPCODES = {
    appendContent: 1,
    getContext: 1,
    lookupWithHelpers: 2,
    lookup: 1,
    invokeMustache: 3,
    pushString: 1,
    truthyOrFallback: 1,
    functionOrFallback: 1,
    invokeProgram: 3,
    invokePartial: 1,
    push: 1,
    assignToHash: 1,
    pushStringParam: 1
  };

  Compiler.DISASSEMBLE_MAP = {};

  for(var prop in Compiler.OPCODE_MAP) {
    var value = Compiler.OPCODE_MAP[prop];
    Compiler.DISASSEMBLE_MAP[value] = prop;
  }

  Compiler.multiParamSize = function(code) {
    return Compiler.MULTI_PARAM_OPCODES[Compiler.DISASSEMBLE_MAP[code]];
  };

  Compiler.prototype = {
    compiler: Compiler,

    disassemble: function() {
      var opcodes = this.opcodes, opcode, nextCode;
      var out = [], str, name, value;

      for(var i=0, l=opcodes.length; i<l; i++) {
        opcode = opcodes[i];

        if(opcode === 'DECLARE') {
          name = opcodes[++i];
          value = opcodes[++i];
          out.push("DECLARE " + name + " = " + value);
        } else {
          str = Compiler.DISASSEMBLE_MAP[opcode];

          var extraParams = Compiler.multiParamSize(opcode);
          var codes = [];

          for(var j=0; j<extraParams; j++) {
            nextCode = opcodes[++i];

            if(typeof nextCode === "string") {
              nextCode = "\"" + nextCode.replace("\n", "\\n") + "\"";
            }

            codes.push(nextCode);
          }

          str = str + " " + codes.join(" ");

          out.push(str);
        }
      }

      return out.join("\n");
    },

    guid: 0,

    compile: function(program, options) {
      this.children = [];
      this.depths = {list: []};
      this.options = options;

      // These changes will propagate to the other compiler components
      var knownHelpers = this.options.knownHelpers;
      this.options.knownHelpers = {
        'helperMissing': true,
        'blockHelperMissing': true,
        'each': true,
        'if': true,
        'unless': true,
        'with': true,
        'log': true
      };
      if (knownHelpers) {
        for (var name in knownHelpers) {
          this.options.knownHelpers[name] = knownHelpers[name];
        }
      }

      return this.program(program);
    },

    accept: function(node) {
      return this[node.type](node);
    },

    program: function(program) {
      var statements = program.statements, statement;
      this.opcodes = [];

      for(var i=0, l=statements.length; i<l; i++) {
        statement = statements[i];
        this[statement.type](statement);
      }
      this.isSimple = l === 1;

      this.depths.list = this.depths.list.sort(function(a, b) {
        return a - b;
      });

      return this;
    },

    compileProgram: function(program) {
      var result = new this.compiler().compile(program, this.options);
      var guid = this.guid++;

      this.usePartial = this.usePartial || result.usePartial;

      this.children[guid] = result;

      for(var i=0, l=result.depths.list.length; i<l; i++) {
        depth = result.depths.list[i];

        if(depth < 2) { continue; }
        else { this.addDepth(depth - 1); }
      }

      return guid;
    },

    block: function(block) {
      var mustache = block.mustache;
      var depth, child, inverse, inverseGuid;

      var params = this.setupStackForMustache(mustache);

      var programGuid = this.compileProgram(block.program);

      if(block.program.inverse) {
        inverseGuid = this.compileProgram(block.program.inverse);
        this.declare('inverse', inverseGuid);
      }

      this.opcode('invokeProgram', programGuid, params.length, !!mustache.hash);
      this.declare('inverse', null);
      this.opcode('append');
    },

    inverse: function(block) {
      var params = this.setupStackForMustache(block.mustache);

      var programGuid = this.compileProgram(block.program);

      this.declare('inverse', programGuid);

      this.opcode('invokeProgram', null, params.length, !!block.mustache.hash);
      this.opcode('append');
    },

    hash: function(hash) {
      var pairs = hash.pairs, pair, val;

      this.opcode('push', '{}');

      for(var i=0, l=pairs.length; i<l; i++) {
        pair = pairs[i];
        val  = pair[1];

        this.accept(val);
        this.opcode('assignToHash', pair[0]);
      }
    },

    partial: function(partial) {
      var id = partial.id;
      this.usePartial = true;

      if(partial.context) {
        this.ID(partial.context);
      } else {
        this.opcode('push', 'depth0');
      }

      this.opcode('invokePartial', id.original);
      this.opcode('append');
    },

    content: function(content) {
      this.opcode('appendContent', content.string);
    },

    mustache: function(mustache) {
      var params = this.setupStackForMustache(mustache);

      this.opcode('invokeMustache', params.length, mustache.id.original, !!mustache.hash);

      if(mustache.escaped) {
        this.opcode('appendEscaped');
      } else {
        this.opcode('append');
      }
    },

    ID: function(id) {
      this.addDepth(id.depth);

      this.opcode('getContext', id.depth);

      this.opcode('lookupWithHelpers', id.parts[0] || null, id.isScoped || false);

      for(var i=1, l=id.parts.length; i<l; i++) {
        this.opcode('lookup', id.parts[i]);
      }
    },

    STRING: function(string) {
      this.opcode('pushString', string.string);
    },

    INTEGER: function(integer) {
      this.opcode('push', integer.integer);
    },

    BOOLEAN: function(bool) {
      this.opcode('push', bool.bool);
    },

    comment: function() {},

    // HELPERS
    pushParams: function(params) {
      var i = params.length, param;

      while(i--) {
        param = params[i];

        if(this.options.stringParams) {
          if(param.depth) {
            this.addDepth(param.depth);
          }

          this.opcode('getContext', param.depth || 0);
          this.opcode('pushStringParam', param.string);
        } else {
          this[param.type](param);
        }
      }
    },

    opcode: function(name, val1, val2, val3) {
      this.opcodes.push(Compiler.OPCODE_MAP[name]);
      if(val1 !== undefined) { this.opcodes.push(val1); }
      if(val2 !== undefined) { this.opcodes.push(val2); }
      if(val3 !== undefined) { this.opcodes.push(val3); }
    },

    declare: function(name, value) {
      this.opcodes.push('DECLARE');
      this.opcodes.push(name);
      this.opcodes.push(value);
    },

    addDepth: function(depth) {
      if(depth === 0) { return; }

      if(!this.depths[depth]) {
        this.depths[depth] = true;
        this.depths.list.push(depth);
      }
    },

    setupStackForMustache: function(mustache) {
      var params = mustache.params;

      this.pushParams(params);

      if(mustache.hash) {
        this.hash(mustache.hash);
      }

      this.ID(mustache.id);

      return params;
    }
  };

  JavaScriptCompiler.prototype = {
    // PUBLIC API: You can override these methods in a subclass to provide
    // alternative compiled forms for name lookup and buffering semantics
    nameLookup: function(parent, name, type) {
			if (/^[0-9]+$/.test(name)) {
        return parent + "[" + name + "]";
      } else if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
	    	return parent + "." + name;
			}
			else {
				return parent + "['" + name + "']";
      }
    },

    appendToBuffer: function(string) {
      if (this.environment.isSimple) {
        return "return " + string + ";";
      } else {
        return "buffer += " + string + ";";
      }
    },

    initializeBuffer: function() {
      return this.quotedString("");
    },

    namespace: "Handlebars",
    // END PUBLIC API

    compile: function(environment, options, context, asObject) {
      this.environment = environment;
      this.options = options || {};

      this.name = this.environment.name;
      this.isChild = !!context;
      this.context = context || {
        programs: [],
        aliases: { self: 'this' },
        registers: {list: []}
      };

      this.preamble();

      this.stackSlot = 0;
      this.stackVars = [];

      this.compileChildren(environment, options);

      var opcodes = environment.opcodes, opcode;

      this.i = 0;

      for(l=opcodes.length; this.i<l; this.i++) {
        opcode = this.nextOpcode(0);

        if(opcode[0] === 'DECLARE') {
          this.i = this.i + 2;
          this[opcode[1]] = opcode[2];
        } else {
          this.i = this.i + opcode[1].length;
          this[opcode[0]].apply(this, opcode[1]);
        }
      }

      return this.createFunctionContext(asObject);
    },

    nextOpcode: function(n) {
      var opcodes = this.environment.opcodes, opcode = opcodes[this.i + n], name, val;
      var extraParams, codes;

      if(opcode === 'DECLARE') {
        name = opcodes[this.i + 1];
        val  = opcodes[this.i + 2];
        return ['DECLARE', name, val];
      } else {
        name = Compiler.DISASSEMBLE_MAP[opcode];

        extraParams = Compiler.multiParamSize(opcode);
        codes = [];

        for(var j=0; j<extraParams; j++) {
          codes.push(opcodes[this.i + j + 1 + n]);
        }

        return [name, codes];
      }
    },

    eat: function(opcode) {
      this.i = this.i + opcode.length;
    },

    preamble: function() {
      var out = [];

      if (!this.isChild) {
        var namespace = this.namespace;
        var copies = "helpers = helpers || " + namespace + ".helpers;";
        if(this.environment.usePartial) { copies = copies + " partials = partials || " + namespace + ".partials;"; }
        out.push(copies);
      } else {
        out.push('');
      }

      if (!this.environment.isSimple) {
        out.push(", buffer = " + this.initializeBuffer());
      } else {
        out.push("");
      }

      // track the last context pushed into place to allow skipping the
      // getContext opcode when it would be a noop
      this.lastContext = 0;
      this.source = out;
    },

    createFunctionContext: function(asObject) {
      var locals = this.stackVars;
      if (!this.isChild) {
        locals = locals.concat(this.context.registers.list);
      }

      if(locals.length > 0) {
        this.source[1] = this.source[1] + ", " + locals.join(", ");
      }

      // Generate minimizer alias mappings
      if (!this.isChild) {
        var aliases = []
        for (var alias in this.context.aliases) {
          this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
        }
      }

      if (this.source[1]) {
        this.source[1] = "var " + this.source[1].substring(2) + ";";
      }

      // Merge children
      if (!this.isChild) {
        this.source[1] += '\n' + this.context.programs.join('\n') + '\n';
      }

      if (!this.environment.isSimple) {
        this.source.push("return buffer;");
      }

      var params = this.isChild ? ["depth0", "data"] : ["Handlebars", "depth0", "helpers", "partials", "data"];

      for(var i=0, l=this.environment.depths.list.length; i<l; i++) {
        params.push("depth" + this.environment.depths.list[i]);
      }

      if (asObject) {
        params.push(this.source.join("\n  "));

        return Function.apply(this, params);
      } else {
        var functionSource = 'function ' + (this.name || '') + '(' + params.join(',') + ') {\n  ' + this.source.join("\n  ") + '}';
        Handlebars.log(Handlebars.logger.DEBUG, functionSource + "\n\n");
        return functionSource;
      }
    },

    appendContent: function(content) {
      this.source.push(this.appendToBuffer(this.quotedString(content)));
    },

    append: function() {
      var local = this.popStack();
      this.source.push("if(" + local + " || " + local + " === 0) { " + this.appendToBuffer(local) + " }");
      if (this.environment.isSimple) {
        this.source.push("else { " + this.appendToBuffer("''") + " }");
      }
    },

    appendEscaped: function() {
      var opcode = this.nextOpcode(1), extra = "";
      this.context.aliases.escapeExpression = 'this.escapeExpression';

      if(opcode[0] === 'appendContent') {
        extra = " + " + this.quotedString(opcode[1][0]);
        this.eat(opcode);
      }

      this.source.push(this.appendToBuffer("escapeExpression(" + this.popStack() + ")" + extra));
    },

    getContext: function(depth) {
      if(this.lastContext !== depth) {
        this.lastContext = depth;
      }
    },

    lookupWithHelpers: function(name, isScoped) {
      if(name) {
        var topStack = this.nextStack();

        this.usingKnownHelper = false;

        var toPush;
        if (!isScoped && this.options.knownHelpers[name]) {
          toPush = topStack + " = " + this.nameLookup('helpers', name, 'helper');
          this.usingKnownHelper = true;
        } else if (isScoped || this.options.knownHelpersOnly) {
          toPush = topStack + " = " + this.nameLookup('depth' + this.lastContext, name, 'context');
        } else {
          toPush =  topStack + " = "
              + this.nameLookup('helpers', name, 'helper')
              + " || "
              + this.nameLookup('depth' + this.lastContext, name, 'context');
        }

        toPush += ';';
        this.source.push(toPush);
      } else {
        this.pushStack('depth' + this.lastContext);
      }
    },

    lookup: function(name) {
      var topStack = this.topStack();
      this.source.push(topStack + " = (" + topStack + " === null || " + topStack + " === undefined || " + topStack + " === false ? " +
 				topStack + " : " + this.nameLookup(topStack, name, 'context') + ");");
    },

    pushStringParam: function(string) {
      this.pushStack('depth' + this.lastContext);
      this.pushString(string);
    },

    pushString: function(string) {
      this.pushStack(this.quotedString(string));
    },

    push: function(name) {
      this.pushStack(name);
    },

    invokeMustache: function(paramSize, original, hasHash) {
      this.populateParams(paramSize, this.quotedString(original), "{}", null, hasHash, function(nextStack, helperMissingString, id) {
        if (!this.usingKnownHelper) {
          this.context.aliases.helperMissing = 'helpers.helperMissing';
          this.context.aliases.undef = 'void 0';
          this.source.push("else if(" + id + "=== undef) { " + nextStack + " = helperMissing.call(" + helperMissingString + "); }");
          if (nextStack !== id) {
            this.source.push("else { " + nextStack + " = " + id + "; }");
          }
        }
      });
    },

    invokeProgram: function(guid, paramSize, hasHash) {
      var inverse = this.programExpression(this.inverse);
      var mainProgram = this.programExpression(guid);

      this.populateParams(paramSize, null, mainProgram, inverse, hasHash, function(nextStack, helperMissingString, id) {
        if (!this.usingKnownHelper) {
          this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
          this.source.push("else { " + nextStack + " = blockHelperMissing.call(" + helperMissingString + "); }");
        }
      });
    },

    populateParams: function(paramSize, helperId, program, inverse, hasHash, fn) {
      var needsRegister = hasHash || this.options.stringParams || inverse || this.options.data;
      var id = this.popStack(), nextStack;
      var params = [], param, stringParam, stringOptions;

      if (needsRegister) {
        this.register('tmp1', program);
        stringOptions = 'tmp1';
      } else {
        stringOptions = '{ hash: {} }';
      }

      if (needsRegister) {
        var hash = (hasHash ? this.popStack() : '{}');
        this.source.push('tmp1.hash = ' + hash + ';');
      }

      if(this.options.stringParams) {
        this.source.push('tmp1.contexts = [];');
      }

      for(var i=0; i<paramSize; i++) {
        param = this.popStack();
        params.push(param);

        if(this.options.stringParams) {
          this.source.push('tmp1.contexts.push(' + this.popStack() + ');');
        }
      }

      if(inverse) {
        this.source.push('tmp1.fn = tmp1;');
        this.source.push('tmp1.inverse = ' + inverse + ';');
      }

      if(this.options.data) {
        this.source.push('tmp1.data = data;');
      }

      params.push(stringOptions);

      this.populateCall(params, id, helperId || id, fn);
    },

    populateCall: function(params, id, helperId, fn) {
      var paramString = ["depth0"].concat(params).join(", ");
      var helperMissingString = ["depth0"].concat(helperId).concat(params).join(", ");

      var nextStack = this.nextStack();

      if (this.usingKnownHelper) {
        this.source.push(nextStack + " = " + id + ".call(" + paramString + ");");
      } else {
        this.context.aliases.functionType = '"function"';
        this.source.push("if(typeof " + id + " === functionType) { " + nextStack + " = " + id + ".call(" + paramString + "); }");
      }
      fn.call(this, nextStack, helperMissingString, id);
      this.usingKnownHelper = false;
    },

    invokePartial: function(context) {
      this.pushStack("self.invokePartial(" + this.nameLookup('partials', context, 'partial') + ", '" + context + "', " + this.popStack() + ", helpers, partials);");
    },

    assignToHash: function(key) {
      var value = this.popStack();
      var hash = this.topStack();

      this.source.push(hash + "['" + key + "'] = " + value + ";");
    },

    // HELPERS

    compiler: JavaScriptCompiler,

    compileChildren: function(environment, options) {
      var children = environment.children, child, compiler;

      for(var i=0, l=children.length; i<l; i++) {
        child = children[i];
        compiler = new this.compiler();

        this.context.programs.push('');     // Placeholder to prevent name conflicts for nested children
        var index = this.context.programs.length;
        child.index = index;
        child.name = 'program' + index;
        this.context.programs[index] = compiler.compile(child, options, this.context);
      }
    },

    programExpression: function(guid) {
      if(guid == null) { return "self.noop"; }

      var child = this.environment.children[guid],
          depths = child.depths.list;
      var programParams = [child.index, child.name, "data"];

      for(var i=0, l = depths.length; i<l; i++) {
        depth = depths[i];

        if(depth === 1) { programParams.push("depth0"); }
        else { programParams.push("depth" + (depth - 1)); }
      }

      if(depths.length === 0) {
        return "self.program(" + programParams.join(", ") + ")";
      } else {
        programParams.shift();
        return "self.programWithDepth(" + programParams.join(", ") + ")";
      }
    },

    register: function(name, val) {
      this.useRegister(name);
      this.source.push(name + " = " + val + ";");
    },

    useRegister: function(name) {
      if(!this.context.registers[name]) {
        this.context.registers[name] = true;
        this.context.registers.list.push(name);
      }
    },

    pushStack: function(item) {
      this.source.push(this.nextStack() + " = " + item + ";");
      return "stack" + this.stackSlot;
    },

    nextStack: function() {
      this.stackSlot++;
      if(this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
      return "stack" + this.stackSlot;
    },

    popStack: function() {
      return "stack" + this.stackSlot--;
    },

    topStack: function() {
      return "stack" + this.stackSlot;
    },

    quotedString: function(str) {
      return '"' + str
        .replace(/\\/g, '\\\\')
        .replace(/"/g, '\\"')
        .replace(/\n/g, '\\n')
        .replace(/\r/g, '\\r') + '"';
    }
  };

  var reservedWords = ("break case catch continue default delete do else finally " +
                       "for function if in instanceof new return switch this throw " +
                       "try typeof var void while with null true false").split(" ");

  var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};

  for(var i=0, l=reservedWords.length; i<l; i++) {
    compilerWords[reservedWords[i]] = true;
  }

	JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
		if(!JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]+$/.test(name)) {
			return true;
		}
		return false;
	}

})(Handlebars.Compiler, Handlebars.JavaScriptCompiler);

Handlebars.precompile = function(string, options) {
  options = options || {};

  var ast = Handlebars.parse(string);
  var environment = new Handlebars.Compiler().compile(ast, options);
  return new Handlebars.JavaScriptCompiler().compile(environment, options);
};

Handlebars.compile = function(string, options) {
  options = options || {};

  var compiled;
  function compile() {
    var ast = Handlebars.parse(string);
    var environment = new Handlebars.Compiler().compile(ast, options);
    var templateSpec = new Handlebars.JavaScriptCompiler().compile(environment, options, undefined, true);
    return Handlebars.template(templateSpec);
  }

  // Template is only compiled on first use and cached after that point.
  return function(context, options) {
    if (!compiled) {
      compiled = compile();
    }
    return compiled.call(this, context, options);
  };
};
;
// lib/handlebars/vm.js
Handlebars.VM = {
  template: function(templateSpec) {
    // Just add water
    var container = {
      escapeExpression: Handlebars.Utils.escapeExpression,
      invokePartial: Handlebars.VM.invokePartial,
      programs: [],
      program: function(i, fn, data) {
        var programWrapper = this.programs[i];
        if(data) {
          return Handlebars.VM.program(fn, data);
        } else if(programWrapper) {
          return programWrapper;
        } else {
          programWrapper = this.programs[i] = Handlebars.VM.program(fn);
          return programWrapper;
        }
      },
      programWithDepth: Handlebars.VM.programWithDepth,
      noop: Handlebars.VM.noop
    };

    return function(context, options) {
      options = options || {};
      return templateSpec.call(container, Handlebars, context, options.helpers, options.partials, options.data);
    };
  },

  programWithDepth: function(fn, data, $depth) {
    var args = Array.prototype.slice.call(arguments, 2);

    return function(context, options) {
      options = options || {};

      return fn.apply(this, [context, options.data || data].concat(args));
    };
  },
  program: function(fn, data) {
    return function(context, options) {
      options = options || {};

      return fn(context, options.data || data);
    };
  },
  noop: function() { return ""; },
  invokePartial: function(partial, name, context, helpers, partials) {
    if(partial === undefined) {
      throw new Handlebars.Exception("The partial " + name + " could not be found");
    } else if(partial instanceof Function) {
      return partial(context, {helpers: helpers, partials: partials});
    } else if (!Handlebars.compile) {
      throw new Handlebars.Exception("The partial " + name + " could not be compiled when running in vm mode");
    } else {
      partials[name] = Handlebars.compile(partial);
      return partials[name](context, {helpers: helpers, partials: partials});
    }
  }
};

Handlebars.template = Handlebars.VM.template;
;

// AMD Define
define('handlebars',[],function(){
    return Handlebars;
});

})();

define('templates/ErrorMessage.hbs',[],function(){return function(e,t,n){n=n||e.helpers;var i,a,o="",r="function";return o+='\n<div class="errorMessage">',a=n.message,a?i=a.call(t,{hash:{}}):(i=t.message,i=typeof i===r?i():i),(i||0===i)&&(o+=i),o+='</div>\n<div class="errorDetails">',a=n.details,a?i=a.call(t,{hash:{}}):(i=t.details,i=typeof i===r?i():i),(i||0===i)&&(o+=i),o+='</div>\n<div class="errorSystemDetails">',a=n.systemMessage,a?i=a.call(t,{hash:{}}):(i=t.systemMessage,i=typeof i===r?i():i),(i||0===i)&&(o+=i),o+="</div>"}});
define('app/Assess',["log","underscore","backbone","deepmodel","marionette","json2","handlebars","templates/ErrorMessage.hbs"],function(e,t,n){"function"!=typeof String.prototype.trim&&(String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g,"")});var i={DEV_STANDALONE:Global.DEV_STANDALONE,API_BASE_URL:Global.API_BASE_URL,BACKBONE_BASE_URL:Global.BACKBONE_BASE_URL,BACKBONE_ROOT:Global.BACKBONE_ROOT,BACKBONE_ROOT_PREFIX_RE:RegExp("^"+Global.BACKBONE_ROOT),humanGradingLinkHref:Global.humanGradingLinkHref,humanGradingLinkText:Global.humanGradingLinkText,app:new n.Marionette.Application,router:null,adminContext:Global.userIsAdmin?"creative_assignment":"",adminMode:Global.userIsAdmin,log:window.log,debug:function(){Array.prototype.slice.apply(arguments),i.log.apply(arguments)},assert:function(e,t){if(!e)throw this.logEvent("system.assertion.fatal",t),"Assertion failed: "+t},expect:function(e,t){return e||this.logEvent("system.assertion.error",t),e},logEvent:function(n,i){var a=t.isObject(i)?i:{message:i};n.indexOf(".fatal")>=0&&e(n,i),Array.prototype.slice.apply(arguments),window.Eventing.send("hg."+n,a)},warn:function(){var e=Array.prototype.slice.apply(arguments);e.unshift("Warning"),i.log.apply(void 0,e)},error:function(){var e=Array.prototype.slice.apply(arguments);e.unshift("Error"),i.log.apply(void 0,e)},scrollToTop:function(){window.scrollTo(0,0)},Routing:{navigate:function(){i.app.vent.trigger("assessmentAlert",null);var e=Array.prototype.slice.call(arguments,0);e[0]=i.BACKBONE_ROOT+e[0],i.router.navigate.apply(this.router,e)},navigateAbsolute:function(){i.app.vent.trigger("assessmentAlert",null);var e=Array.prototype.slice.call(arguments,0);e[0]=e[0].replace(i.BACKBONE_ROOT_PREFIX_RE,"/"),i.router.navigate.apply(this.router,e)},redirect:function(e,t){i.Routing.navigateAbsolute(i.Routing.redirectPath(e)+(t||""),{trigger:!0,replace:!0}),i.scrollToTop()},redirectPath:function(e){var n="";return t(["course","assessment","submission","trainingSet","training","peerGradingSet","peerGrading","selfGradingSet","selfGrading","result","calibrationSet","calibrationGrading"]).each(function(t){var i=e[t+"Id"];null===i?n+="/"+t+"s":i!==void 0&&(n+="/"+t+"s/"+i)}),n=n.replace(/^\//,""),i.BACKBONE_ROOT+n}},ViewModel:n.DeepModel.extend({constructor:function(){var e=Array.prototype.slice.call(arguments),t=this.set;this.set=n.Model.prototype.set,n.DeepModel.prototype.constructor.apply(this,e),this.set=t}})};return i.wrappedViewModel=function(e){return{model:new i.ViewModel(e)}},n.emulateHTTP=!0,n.Marionette.Renderer.render=function(e,t){return e(t)},i.Router=n.Router.extend({constructor:function(e){if(n.Router.prototype.constructor.call(this,e),this.appRoutes){var t=this.controller;e&&e.controller&&(t=e.controller,this.controller=t);var i=this.parentRouter;e&&e.parentRouter&&(i=e.parentRouter,this.parentRouter=i),this.processAppRoutes(t,i,this.appRoutes)}},processAppRoutes:function(e,n,i){var a,o,r,s,l=[],u=this;for(r in i)l.unshift([r,i[r]]);s=l.length;for(var c=0;s>c;c++){r=l[c][0],o=l[c][1],a=t.bind(e[o],e);var d=this.getModelizingMethod(a,e,n);u.route(r,o,d)}},getModelizingMethod:function(e,t,n){var i=e;if(n&&n.controller&&n.controller.modelize){var a=function(){var i=n.controller.modelize.apply(n.controller,Array.prototype.slice.call(arguments));return e.apply(t,i)};i=this.getModelizingMethod(a,t,n.parentRouter)}return i}}),i.app.addRegions({mainRegion:"#main"}),i.Ajax={getCsrfToken:function(e){var n="";return t.find((e(document)[0].cookie||"").split(";"),function(e){return e=(e||"").trim(),0===e.indexOf("csrf_token=")?(n=e.slice(11).trim(),!0):!1}),n},inizIntercept:function(e,t){e.ajaxPrefilter(function(n){n.headers=n.headers||{},n.headers["HG-ACL-ID"]=t,n.headers["X-CSRF-Token"]=i.Ajax.getCsrfToken(e)||""})}},i});
define('models/Course',["app/Assess","backbone","marionette"],function(e,t){var n=t.Model.extend({getBaseUrl:function(){return e.API_BASE_URL},url:function(){return this.getBaseUrl()}});return n});
define('controllers/CoursesController',["app/Assess","models/Course"],function(e,t){var n={course:null,modelize:function(){var e=Array.prototype.slice.call(arguments),n=e.shift();return this.course||(this.course=new t({id:n})),[this.course].concat(e)},index:function(){var t="route.error",n={};e.logEvent(t,n),e.Routing.navigate("courses/PLEASE_REPORT_THIS_BUG",!0)}};return n});
define('routers/CoursesRouting',["app/Assess","jquery","underscore","backbone","controllers/CoursesController"],function(e,t,n,i,a){var o={};return o.Router=e.Router.extend({appRoutes:{"":"index"}}),o.router=new o.Router({controller:a}),e.router=o.router,t("body").on("click","a.hg-internal",function(n){var i=t(n.currentTarget).attr("href");n.ctrlKey||"#"===i||(n.preventDefault(),e.Routing.navigateAbsolute(i,!0))}),o});
define('lib/Util',["jquery","underscore"],function(e,t){var n=0,i={sparkUrl:function(e){return window.Global.COURSE_BASE_URL+e},siteAssetUrl:function(e){return window.Global.SITES_ASSETS_BASE_URL+e},getElement:function(e,n,i){return e&&t.has(e,n)?e[n]:i},capitalize:function(e){return e.charAt(0).toUpperCase()+e.slice(1)},fromTimeStringToLocaleString:function(e){var t=new Date(1e3*parseInt(e,10));return t.toLocaleString()},ifAndWhen:function(t,n){return t&&n||e.Deferred().reject().promise()},ifOrWhen:function(t,n){return t&&e.Deferred().resolve().promise()||n},round:function(e,t){return e===void 0||null===e?e:(t=t||0,Math.round(e*Math.pow(10,t))/Math.pow(10,t))},mkGUID:function(){var e,t=(new Date).getTime().toString(32);for(e=0;5>e;++e)t+=Math.floor(65535*Math.random()).toString(32);return t+(++n).toString(32)},getUrlParam:function(e,t){t=t.replace(/[\[]/,"\\[").replace(/[\]]/,"\\]");var n="[\\?&]"+t+"=([^&#]*)",i=RegExp(n),a=i.exec(window.unescape(e));return null===a?null:a[1]}};return i});
/* ===================================================
 * bootstrap-transition.js v2.0.2
 * http://twitter.github.com/bootstrap/javascript.html#transitions
 * ===================================================
 * Copyright 2012 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ========================================================== */

!function( $ ) {

  $(function () {

    "use strict"

    /* CSS TRANSITION SUPPORT (https://gist.github.com/373874)
     * ======================================================= */

    $.support.transition = (function () {
      var thisBody = document.body || document.documentElement
        , thisStyle = thisBody.style
        , support = thisStyle.transition !== undefined || thisStyle.WebkitTransition !== undefined || thisStyle.MozTransition !== undefined || thisStyle.MsTransition !== undefined || thisStyle.OTransition !== undefined

      return support && {
        end: (function () {
          var transitionEnd = "TransitionEnd"
          if ( $.browser.webkit ) {
          	transitionEnd = "webkitTransitionEnd"
          } else if ( $.browser.mozilla ) {
          	transitionEnd = "transitionend"
          } else if ( $.browser.opera ) {
          	transitionEnd = "oTransitionEnd"
          }
          return transitionEnd
        }())
      }
    })()

  })

}( window.jQuery );
define("bootstrap_transition", ["jquery"], function(){});

/* ==========================================================
 * bootstrap-alert.js v2.0.2
 * http://twitter.github.com/bootstrap/javascript.html#alerts
 * ==========================================================
 * Copyright 2012 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ========================================================== */


!function( $ ){

  "use strict"

 /* ALERT CLASS DEFINITION
  * ====================== */

  var dismiss = '[data-dismiss="alert"]'
    , Alert = function ( el ) {
        $(el).on('click', dismiss, this.close)
      }

  Alert.prototype = {

    constructor: Alert

  , close: function ( e ) {
      var $this = $(this)
        , selector = $this.attr('data-target')
        , $parent

      if (!selector) {
        selector = $this.attr('href')
        selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
      }

      $parent = $(selector)
      $parent.trigger('close')

      e && e.preventDefault()

      $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())

      $parent
        .trigger('close')
        .removeClass('in')

      function removeElement() {
        $parent
          .trigger('closed')
          .remove()
      }

      $.support.transition && $parent.hasClass('fade') ?
        $parent.on($.support.transition.end, removeElement) :
        removeElement()
    }

  }


 /* ALERT PLUGIN DEFINITION
  * ======================= */

  $.fn.alert = function ( option ) {
    return this.each(function () {
      var $this = $(this)
        , data = $this.data('alert')
      if (!data) $this.data('alert', (data = new Alert(this)))
      if (typeof option == 'string') data[option].call($this)
    })
  }

  $.fn.alert.Constructor = Alert


 /* ALERT DATA-API
  * ============== */

  $(function () {
    $('body').on('click.alert.data-api', dismiss, Alert.prototype.close)
  })

}( window.jQuery );
define("bootstrap_alert", ["jquery","bootstrap_transition"], function(){});

define('models/Submission',["app/Assess","jquery","underscore","backbone","marionette"],function(e,t,n,i){var a=i.DeepModel.extend({assessment:null,fetch:function(){return"preview"===this.id?(this.set(this.parse({submitTime:"123"})),t.Deferred().resolve().promise()):this.constructor.__super__.fetch.apply(this,arguments)},getBaseUrl:function(){return e.API_BASE_URL},url:function(){return this.isNew()?(e.assert(this.assessment,"this.assessment undefined on submission "+this.id),this.assessment.url()+"/submissions"):this.getBaseUrl()+"submissions/"+this.id},getAssessment:function(){return this.assessment}},{SIGNATURE_STATUS:{NOT_IN_SIGNATURE_TRACK:"notInSignatureTrack",AUTHENTICATION_ATTEMPT_DISALLOWED:"authenticationAttemptDisallowed",AUTHENTICATION_ATTEMPT_ALLOWED:"authenticationAttemptAllowed",AUTHENTICATION_PENDING:"authenticationPending",AUTHENTICATION_PASSED:"authenticationPassed",AUTHENTICATION_FAILED:"authenticationFailed"}});return a});
define('templates/AssessmentsLayout.hbs',[],function(){return function(e,t,n){return n=n||e.helpers,'\n<div id="assessmentContainer" aria-live="polite" class="container-fluid">\n  <div id="assessmentNavigationRegion" class="navigationRegion"></div>\n  <div id="assessmentMessages"></div>\n  <div id="assessmentContentRegion" class="contentRegion"></div>\n</div>'}});
define('views/AssessmentsLayout',["app/Assess","underscore","backbone","marionette","handlebars","models/Submission","templates/AssessmentsLayout.hbs"],function(e,t,n,i,a,o,r){a.registerHelper("eachWithIndex",function(e,n){for(var i="",a=0,o=e.size();o>a;a++)i+=n.fn(t.extend(e.at(a),{index:a+1}));return i});var s=n.Marionette.Layout.extend({template:function(){return a.template(r)},tagName:"div",id:"AssessmentsLayout",regions:{navigationRegion:"#assessmentNavigationRegion",contentRegion:"#assessmentContentRegion"}});return s});
define('views/ViewHelpers',["app/Assess","lib/Util","jquery","handlebars","templates/ErrorMessage.hbs"],function(e,t,n,i,a){i.registerHelper("fromTimeStringToLocaleString",function(e){return e?t.fromTimeStringToLocaleString(e):""}),i.registerHelper("author",function(e){return e.get("authorName")?e.get("authorName"):e.get("authorId")?"Student "+e.get("authorId"):""}),i.registerHelper("resetCounter",function(e){return this[e]=0,""}),i.registerHelper("incrementCounter",function(e){return this[e]++,""});var o={showLoadingIndicator:function(e,t,n){var i="";i+='<span class="loadingIndicatorContainer" id="'+n+"_Container"+'">',i+='<span class="loadingIndicatorDisplay" id="'+n+"_Display"+'"></span>',t&&(i+='&nbsp; &nbsp; <span class="loadingIndicatorMessage" id="'+n+"_Message"+'">'+t+"</span>"),i+="</span>",e.first().after(i),e.hide()},hideLoadingIndicator:function(e,t){e.show(),n("#"+t+"_Container").remove()},alertErrorHtml:function(e){return i.template(a)(e)},alertError:function(t){e.app.vent.trigger("assessmentAlert",{type:"error",html:this.alertErrorHtml({message:t})})},alertAjaxError:function(t,n,i,a){var o=(i||"")+(n&&n.responseText?": "+n.responseText:""),r=this.alertErrorHtml({message:t,details:o&&"Reason: "+o||"",systemMessage:(n&&n.status||"")+(a&&" ("+a+")"||"")});e.app.vent.trigger("assessmentAlert",{type:"error",html:r}),e.logEvent("alert.error",{messageHtml:t.replace(/\n/g," "),xhr:n,statusText:i,errorThrown:a})},alertSimpleError:function(t,n){o.alertError(t),e.logEvent("user.validation.error",{errorJson:n})}};return o});
(function(){var e=function(e){var t=function(e,t){this.init("tooltip",e,t)};t.prototype={constructor:t,init:function(t,i,n){var a,o;this.type=t,this.$element=e(i),this.options=this.getOptions(n),this.enabled=!0,"manual"!=this.options.trigger&&(a="hover"==this.options.trigger?"mouseenter":"focus",o="hover"==this.options.trigger?"mouseleave":"blur",this.$element.on(a,this.options.selector,e.proxy(this.enter,this)),this.$element.on(o,this.options.selector,e.proxy(this.leave,this))),this.options.selector?this._options=e.extend({},this.options,{trigger:"manual",selector:""}):this.fixTitle()},getOptions:function(t){return t=e.extend({},e.fn[this.type].defaults,t,this.$element.data()),t.delay&&"number"==typeof t.delay&&(t.delay={show:t.delay,hide:t.delay}),t},enter:function(t){var i=e(t.currentTarget)[this.type](this._options).data(this.type);return i.options.delay&&i.options.delay.show?(clearTimeout(this.timeout),i.hoverState="in",this.timeout=window.setTimeout(function(){"in"==i.hoverState&&i.show()},i.options.delay.show),void 0):i.show()},leave:function(t){var i=e(t.currentTarget)[this.type](this._options).data(this.type);return this.timeout&&clearTimeout(this.timeout),i.options.delay&&i.options.delay.hide?(i.hoverState="out",this.timeout=window.setTimeout(function(){"out"==i.hoverState&&i.hide()},i.options.delay.hide),void 0):i.hide()},show:function(){var e,t,i,n,a,o,r;if(this.hasContent()&&this.enabled){switch(e=this.tip(),this.setContent(),this.options.animation&&e.addClass("fade"),o="function"==typeof this.options.placement?this.options.placement.call(this,e[0],this.$element[0]):this.options.placement,t=/in/.test(o),e.remove().css({top:0,left:0,display:"block"}).appendTo(t?this.$element:document.body),i=this.getPosition(t),n=e[0].offsetWidth,a=e[0].offsetHeight,t?o.split(" ")[1]:o){case"bottom":r={top:i.top+i.height,left:i.left+i.width/2-n/2};break;case"top":r={top:i.top-a,left:i.left+i.width/2-n/2};break;case"left":r={top:i.top+i.height/2-a/2,left:i.left-n};break;case"right":r={top:i.top+i.height/2-a/2,left:i.left+i.width}}e.css(r).addClass(o).addClass("in")}},isHTML:function(e){return"string"!=typeof e||"<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3||/^(?:[^<]*<[\w\W]+>[^>]*$)/.exec(e)},setContent:function(){var e=this.tip(),t=this.getTitle();e.find(".tooltip-inner")[this.isHTML(t)?"html":"text"](t),e.removeClass("fade in top bottom left right")},hide:function(){function t(){var t=window.setTimeout(function(){i.off(e.support.transition.end).remove()},500);i.one(e.support.transition.end,function(){clearTimeout(t),i.remove()})}var i=this.tip();i.removeClass("in"),e.support.transition&&this.$tip.hasClass("fade")?t():i.remove()},fixTitle:function(){var e=this.$element;(e.attr("title")||"string"!=typeof e.attr("data-original-title"))&&e.attr("data-original-title",e.attr("title")||"").removeAttr("title")},hasContent:function(){return this.getTitle()},getPosition:function(t){return e.extend({},t?{top:0,left:0}:this.$element.offset(),{width:this.$element[0].offsetWidth,height:this.$element[0].offsetHeight})},getTitle:function(){var e,t=this.$element,i=this.options;return e=t.attr("data-original-title")||("function"==typeof i.title?i.title.call(t[0]):i.title)},tip:function(){return this.$tip=this.$tip||e(this.options.template)},validate:function(){this.$element[0].parentNode||(this.hide(),this.$element=null,this.options=null)},enable:function(){this.enabled=!0},disable:function(){this.enabled=!1},toggleEnabled:function(){this.enabled=!this.enabled},toggle:function(){this[this.tip().hasClass("in")?"hide":"show"]()}},e.fn.tooltip=function(i){return this.each(function(){var n=e(this),a=n.data("tooltip"),o="object"==typeof i&&i;a||n.data("tooltip",a=new t(this,o)),"string"==typeof i&&a[i]()})},e.fn.tooltip.Constructor=t,e.fn.tooltip.defaults={animation:!0,placement:"top",selector:!1,template:'<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',trigger:"hover",title:"",delay:0}};"function"==typeof define&&define.amd?define('bootstrap_tooltip',["jquery"],function(t){e(t)}):"undefined"!=typeof window&&"undefined"==typeof ender&&e(window.$)})();
(function(){var e=function(e){var t=function(e,t){this.init("popover",e,t)};t.prototype=e.extend({},e.fn.tooltip.Constructor.prototype,{constructor:t,setContent:function(){var e=this.tip(),t=this.getTitle(),i=this.getContent();e.find(".popover-title")[this.isHTML(t)?"html":"text"](t),e.find(".popover-content > *")[this.isHTML(i)?"html":"text"](i),e.removeClass("fade top bottom left right in")},hasContent:function(){return this.getTitle()||this.getContent()},getContent:function(){var e,t=this.$element,i=this.options;return e=t.attr("data-content")||("function"==typeof i.content?i.content.call(t[0]):i.content)},tip:function(){return this.$tip||(this.$tip=e(this.options.template)),this.$tip}}),e.fn.popover=function(i){return this.each(function(){var a=e(this),o=a.data("popover"),n="object"==typeof i&&i;o||a.data("popover",o=new t(this,n)),"string"==typeof i&&o[i]()})},e.fn.popover.Constructor=t,e.fn.popover.defaults=e.extend({},e.fn.tooltip.defaults,{placement:"right",content:"",template:'<div class="popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'})};"function"==typeof define&&define.amd?define('bootstrap_popover',["jquery","bootstrap_tooltip"],function(t){e(t)}):"undefined"!=typeof window&&"undefined"==typeof ender&&e(window.$)})();
(function(){var e=function(e,t){if(e.cleanData){var i=e.cleanData;e.cleanData=function(t){for(var a,n=0;null!=(a=t[n]);n++)try{e(a).triggerHandler("remove")}catch(o){}i(t)}}else{var a=e.fn.remove;e.fn.remove=function(t,i){return this.each(function(){return i||(!t||e.filter(t,[this]).length)&&e("*",this).add([this]).each(function(){try{e(this).triggerHandler("remove")}catch(t){}}),a.call(e(this),t,i)})}}e.widget=function(t,i,a){var n,o=t.split(".")[0];t=t.split(".")[1],n=o+"-"+t,a||(a=i,i=e.Widget),e.expr[":"][n]=function(i){return!!e.data(i,t)},e[o]=e[o]||{},e[o][t]=function(e,t){arguments.length&&this._createWidget(e,t)};var r=new i;r.options=e.extend(!0,{},r.options),e[o][t].prototype=e.extend(!0,r,{namespace:o,widgetName:t,widgetEventPrefix:e[o][t].prototype.widgetEventPrefix||t,widgetBaseClass:n},a),e.widget.bridge(t,e[o][t])},e.widget.bridge=function(i,a){e.fn[i]=function(n){var o="string"==typeof n,r=Array.prototype.slice.call(arguments,1),s=this;return n=!o&&r.length?e.extend.apply(null,[!0,n].concat(r)):n,o&&"_"===n.charAt(0)?s:(o?this.each(function(){var a=e.data(this,i),o=a&&e.isFunction(a[n])?a[n].apply(a,r):a;return o!==a&&o!==t?(s=o,!1):t}):this.each(function(){var t=e.data(this,i);t?t.option(n||{})._init():e.data(this,i,new a(n,this))}),s)}},e.Widget=function(e,t){arguments.length&&this._createWidget(e,t)},e.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",options:{disabled:!1},_createWidget:function(t,i){e.data(i,this.widgetName,this),this.element=e(i),this.options=e.extend(!0,{},this.options,this._getCreateOptions(),t);var a=this;this.element.bind("remove."+this.widgetName,function(){a.destroy()}),this._create(),this._trigger("create"),this._init()},_getCreateOptions:function(){return e.metadata&&e.metadata.get(this.element[0])[this.widgetName]},_create:function(){},_init:function(){},destroy:function(){this.element.unbind("."+this.widgetName).removeData(this.widgetName),this.widget().unbind("."+this.widgetName).removeAttr("aria-disabled").removeClass(this.widgetBaseClass+"-disabled "+"ui-state-disabled")},widget:function(){return this.element},option:function(i,a){var n=i;if(0===arguments.length)return e.extend({},this.options);if("string"==typeof i){if(a===t)return this.options[i];n={},n[i]=a}return this._setOptions(n),this},_setOptions:function(t){var i=this;return e.each(t,function(e,t){i._setOption(e,t)}),this},_setOption:function(e,t){return this.options[e]=t,"disabled"===e&&this.widget()[t?"addClass":"removeClass"](this.widgetBaseClass+"-disabled"+" "+"ui-state-disabled").attr("aria-disabled",t),this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_trigger:function(t,i,a){var n,o,r=this.options[t];if(a=a||{},i=e.Event(i),i.type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),i.target=this.element[0],o=i.originalEvent)for(n in o)n in i||(i[n]=o[n]);return this.element.trigger(i,a),!(e.isFunction(r)&&r.call(this.element[0],i,a)===!1||i.isDefaultPrevented())}}};"function"==typeof define&&define.amd?define('jquery.ui.widget',["jquery"],e):e(jQuery)})();
(function(){var e=function(e,t,i){function a(e,t){var i,a,o,n,s,r,l;60>e?(i=e,a="second",l=1e3):3600>e?(i=e/60,a="minute",l=1e3,0!==e%60&&(o=e%60,n="second")):86400>e?(i=e/3600,a="hour",l=6e4,0!==e%3600&&(o=Math.ceil(e%3600/60),n="minute")):604800>e?(i=e/86400,a="day",l=36e5,0!==e%86400&&(o=Math.ceil(e%86400/3600),n="hour")):2629740>e?(i=e/604800,a="week",l=864e5,0!==e%604800&&(o=Math.ceil(e%604800/86400),n="day")):(i=e/2629740,a="month",l=6048e5,0!==e%2629740&&(o=Math.ceil(e%2629740/604800),n="week"));var u=a,c=n;if(i=Math.floor(i),1!==i&&(a+="s"),o&&1!==o&&(n+="s"),r=i+" "+a,o&&n&&(r+=", "+o+" "+n),"binary-concise"===t){var d={second:{primary:"sec",secondary:"s"},minute:{primary:"min",secondary:"m"},hour:{primary:"hr",secondary:"h"},day:{primary:"day",secondary:"d"},week:{primary:"wk",secondary:"w"},month:{primary:"mon",secondary:"m"},year:{primary:"yr",secondary:"y"}};s=i+d[u].primary,o&&n&&(s+=" "+o+d[c].secondary)}else s=r;return{text:s,fullText:r,updateInterval:l}}function o(e,t){return Math.ceil(Math.abs(t-e)/1e3)}function n(e,t,i){return e===void 0||null===e?t:"function"==typeof e?e.call(null,t,i):e.replace(/%s/,t).replace(/%s/,i).replace(/%1\$s/,t).replace(/%2\$s/,i)}e.widget("coursera.livetimer",{options:{relative:{pastFormat:"%s ago",futureFormat:"in %s",style:"binary-full"},title:{pastFormat:"%1$s",futureFormat:"%1$s"},cycle:{fx:"fade",containerResize:!1,slideResize:!1},display:"cycle"},dateIsPast:!1,_create:function(){var e=this.getDate();if(!isNaN(e)){this.element.text()||this.element.text(e.toLocaleString()),this.element.attr("data-livetimer-date-original",this.element.text()),this.element.attr("title")||this.element.data("livetimer-set-title",!0);var t='<span class="livetimer-absolute">'+this.element.html()+"</span>";t+='<span class="livetimer-relative"></span>';var i=this.element.height(),a=this.element.width();this.element.html(t).css({height:i,width:a}),this._update()}},_init:function(){this.dateIsPast=this.isPast(),"cycle"===this.options.display?this.element.cycle(this.options.cycle):"relative"===this.options.display?(this.element.children(".livetimer-absolute").hide(),this.element.children(".livetimer-relative").show()):"absolute"===this.options.display?(this.element.children(".livetimer-relative").hide(),this.element.children(".livetimer-absolute").show()):"absoluteAndRelative"===this.options.display&&(this.element.children(".livetimer-absolute").show(),this.element.children(".livetimer-relative").show())},_setOption:function(t){"cycleOptions"===t&&this.element.cycle(this.options.cycle),e.Widget.prototype._setOption.apply(this,arguments),"display"===t&&this._update()},_update:function(){var e,i,s,r,l,u,c=this,d=new Date,p=this.getDate();if(isNaN(p))e=i=this.getFormattedDateString(),s=1e3,this.element.data("livetimer-set-title",null);else{var h=null,f=null;d>=p?(this.options.relative&&(h=this.options.relative.pastFormat),this.options.absolute&&(f=this.options.absolute.pastFormat),u=this.options.title.pastFormat):(this.options.relative&&(h=this.options.relative.futureFormat),this.options.absolute&&(f=this.options.absolute.futureFormat),u=this.options.title.futureFormat);var m=a(o(d,p),this.options.relative.style),g=m.text;r=m.fullText,l=this.getFormattedDateString(),e=n(h,g),i=n(f,l),s=m.updateInterval}this.element.children(".livetimer-relative").html(e),this.element.children(".livetimer-absolute").html(i),this.element.data("livetimer-set-title")&&this.element.attr("title",n(u,l,r)),!this.dateIsPast&&d>=p&&(this.dateIsPast=!0,this._trigger("hasPassed")),t.setTimeout(function(){c._update(),c._trigger("tick")},s)},isPast:function(){var e=new Date,t=this.getDate();return isNaN(t)?void 0:e>=t},getDateOriginal:function(){return this.element.attr("data-livetimer-date-original")},getDate:function(){var e=parseInt(this.element.attr("data-livetimer-date-primitive"),10);return!isNaN(e)&&new Date(e)},getFormattedDateString:function(){if(this.options.absolute.momentReformat&&i){var e=this.getDate();return e=i(e),e.format("function"==typeof this.options.absolute.momentReformat?this.options.absolute.momentReformat.call(e):this.options.absolute.momentReformat)}return this.getDateOriginal()},destroy:function(){this.element.html(this.element.children(".livetimer-absolute").html()),e.Widget.prototype.destroy.call(this)}})};"function"==typeof define&&define.amd?define("jquery.livetimer",["jquery","jquery.ui.widget"],function(t,i,a){return e(t,window,a)}):e(jQuery,window,window.moment)})();
define('models/AssessmentAccess',["app/Assess","lib/Util","jquery","underscore","backbone"],function(e,t,n,i,a){var o=a.Model.extend({defaults:{calibrate:"rwi"}}),r=a.Model.extend({defaults:{submitting:"",training:"",peerGrading:"",selfGrading:"",results:""}}),s=a.Model.extend({defaults:{currentPhase:null,adminAccess:new o,studentAccess:new r},initialize:function(){this.overrideIfPreview()},extractAccessFromXhr:function(e,t){var n=this,a=e.getResponseHeader("HG-ACL");a&&(n.update(JSON.parse(a)),i.isFunction(t)&&t())},update:function(e){var t=this,n=t.get("studentAccess");i.each(n.attributes,function(t,a){i.has(e,a)&&n.set(a,e[a])}),t.set({currentPhase:e.phase}),t.overrideIfPreview(),this.trigger("update")},overrideIfPreview:function(){var e=this;if(this.attributes.previewPhase){e.set({currentPhase:this.attributes.previewPhase});var t=e.get("studentAccess");i.each(t.defaults,function(e,n){t.set(n,"rw")})}},getBestStep:function(){return this.attributes.previewPhase?this.attributes.previewPhase:e.adminMode?"creative_assignment"===e.adminContext?"calibrate":"":this.findLastReadableStep()},isStepInaccessible:function(e){return!this.isStepWritable(e)&&!this.isStepReadable(e)},isStepWritable:function(e){return this.stepHasFlag(e,"w")},isStepReadable:function(e){return this.stepHasFlag(e,"r")},isStepCompleted:function(e){return!this.stepHasFlag(e,"i")},stepHasFlag:function(e,t){var n=this,a=n.get("adminAccess");return i.has(a,e)?(a.get(e)||"").indexOf(t)>=0:(n.get("studentAccess").get(e)||"").indexOf(t)>=0},findLastReadableStep:function(){var e=this,t=i.find(s.STEPS_ORDER.slice().reverse(),function(t){return e.isStepReadable(t)});return t}},{STEPS:{submitting:{phase:"submitting",verbalPhrase:"do your assignment",gerundPhrase:"your assignment"},training:{phase:"grading",verbalPhrase:"train",gerundPhrase:"training",blockerStep:"submitting"},peerGrading:{phase:"grading",verbalPhrase:"evaluate your peers",gerundPhrase:"evaluating your peers",blockerStep:"training"},selfGrading:{phase:"grading",verbalPhrase:"self-evaluate",gerundPhrase:"self-evaluating",blockerStep:"peerGrading"},results:{phase:"results",verbalPhrase:"see your results",blockerStep:"selfGrading"}},STEPS_ORDER:["submitting","training","peerGrading","selfGrading","results"],PHASES:{"pre-submitting":{order:.5,text:"pre-submission"},submitting:{order:1,text:"submission"},"pre-grading":{order:1.5,text:"pre-evaluation"},grading:{order:2,text:"evaluation"},"pre-results":{order:2.5,text:"pre-evaluation"},results:{order:3,text:"results"}},phaseOrder:function(e){return s.PHASES[e].order}});return s});
define('models/AssessmentNavigationViewModel',["app/Assess","backbone","marionette","handlebars"],function(e,t,n,i){var a=t.Model.extend({initialize:function(){i.registerHelper("assessmentPath",function(){return e.BACKBONE_ROOT+"courses/"+this.assessment.course.id+"/assessments/"+this.assessment.id}),i.registerHelper("ifPolicyHasEnabled",function(e,t){return this.assessment.isStepEnabled(e)?t.fn(this):""}),i.registerHelper("ifSharingIsEnabled",function(e,t){return this.assessment.isSharingEnabled()?t.fn(this):""}),i.registerHelper("humanGradingLinkHref",function(){return e.humanGradingLinkHref}),i.registerHelper("humanGradingLinkText",function(){return e.humanGradingLinkText})}});return a});
define('views/BaseView',["app/Assess","jquery","underscore","backbone","marionette","json2","views/ViewHelpers"],function(e,t,n,i,a,o,r){var s=i.Marionette.ItemView.extend({handleApiErrors:function(e,t,i,a){var s="";if(460===e.status){var l=o.parse(e.responseText);if("errors"===l.responseType){n.each(l.details,function(e){var t="",n=a+" ";if("access"===e.errorType)switch(e.reason){case"notOwner":t+="You are not the owner of this submission. ";break;case"notAdmin":t+="You do not have administrator privileges. ";break;case"notAssigned":t+="You were not assigned this submission. ";break;case"beforePhase":t+="That part of the assessment has not started yet. ",n+="Please try again later. ";break;case"afterPhase":t+="Sorry, the deadline has passed. ";break;case"submittingIncomplete":t+="You did not submit any work during the submission phase, which is required to continue. ";break;case"trainingDisabled":t+="There is no training for this assessment. ";break;case"trainingNotAttempted":t+="You did not attempt the training exercises. ";break;case"trainingIncomplete":t+="You did not complete the training exercises, which are required to receive an evaluation from your peers. ";break;case"trainingFail":t+="Sorry, you did not pass training and training is no longer available. ";break;case"trainingExhausted":t+="You have completed training and there are no more exercises. ";break;case"peerGradingNotAttempted":t+="You did not start the peer-evaluation tasks. ";break;case"peerGradingIncomplete":t+="You did not complete the peer-evaluation work, which is required to receive an evaluation from your peers. ";break;case"selfGradingDisabled":t+="Self-evaluation is not enabled for this assessment. ";break;case"selfGradingNotAttempted":t+="You did not start the self-evaluation tasks. ";break;case"selfGradingIncomplete":t+="You did not complete the self-evaluation work, which is required to receive an evaluation from your peers. "}s+=t+n+"<br />"});var u=n.filter(l.details,function(e){return 0===e.errorType.indexOf("validation.")});return u.length&&(s+="See below for details.",this.displayFieldErrors(u)),r.alertSimpleError(s),void 0}}r.alertAjaxError(s,e,t,i)},onRender:function(){for(var e=n.reject(n.keys(this.model.attributes),function(e){return e.length>5&&"Model"===e.substring(e.length-5)}),t={},i=0;e.length>i;i++)t[e[i]]=this.model.attributes[e[i]];var a=this.parseViewModel(t,0);window.Eventing.setCandy(a)},parseViewModel:function(e,t){if(!(t>2)){var a,o=this;return n.isArray(e)||e instanceof i.Collection?(a=[],e.forEach(function(e){var i=o.parseViewModel(e,t+1);n.isEmpty(i)||a.push(i)})):n.isObject(e)&&(a={},n.each(e,function(r,s){if(!n.isObject(r)||e instanceof i.Model&&"_previousAttributes"===s)"id"===s&&(a[s]=r);else{var l=o.parseViewModel(r,t+1);n.isEmpty(l)||(a[s]=l)}})),a}}});return s});
define('templates/CreativeAssignmentNavView.hbs',[],function(){return function(e,t,n){n=n||e.helpers;var i,a,o="",r="function",s=this.escapeExpression;return o+='\n<ul class="breadcrumb">\n  <li><a href="',a=n.humanGradingLinkHref,a?i=a.call(t,{hash:{}}):(i=t.humanGradingLinkHref,i=typeof i===r?i():i),o+=s(i)+'">',a=n.humanGradingLinkText,a?i=a.call(t,{hash:{}}):(i=t.humanGradingLinkText,i=typeof i===r?i():i),o+=s(i)+'</a></li>\n  <li><span class="divider">/</span>',i=t.assessment,i=null==i||i===!1?i:i.attributes,i=null==i||i===!1?i:i.title,i=typeof i===r?i():i,o+=s(i)+"</li>\n</ul>"}});
define('templates/AssessmentNavigationView.hbs',[],function(){return function(e,t,n,i,a){function o(e){var t,i,a="";return a+='\n            <li id="hg-nav-step-training" class="hg-nav-step"><a href="',i=n.assessmentPath,i?t=i.call(e,{hash:{}}):(t=e.assessmentPath,t=typeof t===c?t():t),a+=d(t)+'/trainingSets" class="hg-internal">',i=n.incrementCounter,t=i?i.call(e,"step",{hash:{}}):p.call(e,"incrementCounter","step",{hash:{}}),a+=d(t)+'<span class="step">',i=n.step,i?t=i.call(e,{hash:{}}):(t=e.step,t=typeof t===c?t():t),a+=d(t)+'.</span><span>Train</span><span class="hg-nav-step-status"><span class="hg-nav-step-status-todo icon-check-empty"></span><span class="hg-nav-step-status-other"></span></span></a></li>'}function r(e){var t,i,a="";return a+='\n            <li id="hg-nav-step-selfGrading" class="hg-nav-step"><a href="',i=n.assessmentPath,i?t=i.call(e,{hash:{}}):(t=e.assessmentPath,t=typeof t===c?t():t),a+=d(t)+'/selfGradingSets" class="hg-internal">',i=n.incrementCounter,t=i?i.call(e,"step",{hash:{}}):p.call(e,"incrementCounter","step",{hash:{}}),a+=d(t)+'<span class="step">',i=n.step,i?t=i.call(e,{hash:{}}):(t=e.step,t=typeof t===c?t():t),a+=d(t)+'.</span><span>Self-evaluate</span><span class="hg-nav-step-status"><span class="hg-nav-step-status-todo icon-check-empty"></span><span class="hg-nav-step-status-other"></span></span></a></li>'}n=n||e.helpers;var s,l,u="",c="function",d=this.escapeExpression,p=n.helperMissing,h=this;return u+='\n<ul class="breadcrumb">\n  <li><a href="',l=n.humanGradingLinkHref,l?s=l.call(t,{hash:{}}):(s=t.humanGradingLinkHref,s=typeof s===c?s():s),u+=d(s)+'">',l=n.humanGradingLinkText,l?s=l.call(t,{hash:{}}):(s=t.humanGradingLinkText,s=typeof s===c?s():s),u+=d(s)+'</a></li>\n  <li><span class="divider">/</span>',s=t.assessment,s=null==s||s===!1?s:s.attributes,s=null==s||s===!1?s:s.title,s=typeof s===c?s():s,u+=d(s)+"</li>\n</ul>",l=n.resetCounter,s=l?l.call(t,"step",{hash:{}}):p.call(t,"resetCounter","step",{hash:{}}),u+=d(s)+'\n<div class="navbar">\n  <div class="navbar-inner">\n    <div class="container">\n      <ul id="hg-nav" class="nav">\n        <li id="hg-nav-phase-submitting" class="hg-nav-phase hg-nav-border-left hg-nav-border-right">\n          <div class="hg-nav-top-row">\n            <div class="progress">\n              <div class="bar"></div>\n            </div>\n            <div class="hg-asst-interval">\n              <div class="hg-asst-interval-part hg-asst-interval-open"><span data-livetimer-date-primitive="',s=t.assessment,s=null==s||s===!1?s:s.attributes,s=null==s||s===!1?s:s.openTimeEffective,s=typeof s===c?s():s,u+=d(s)+'000" class="hg-date">',s=t.assessment,s=null==s||s===!1?s:s.attributes,s=null==s||s===!1?s:s.openTimeString,s=typeof s===c?s():s,u+=d(s)+'</span></div>\n              <div class="hg-asst-interval-part hg-asst-interval-close"><span data-livetimer-date-primitive="',s=t.assessment,s=null==s||s===!1?s:s.attributes,s=null==s||s===!1?s:s.submissionDeadlineEffective,s=typeof s===c?s():s,u+=d(s)+'000" class="hg-date">',s=t.assessment,s=null==s||s===!1?s:s.attributes,s=null==s||s===!1?s:s.submissionDeadlineString,s=typeof s===c?s():s,u+=d(s)+'</span></div>\n            </div>\n            <div class="hg-asst-phase-reload"><a href="#" class="hg-internal hg-reload">Reload</a>&nbsp;to open</div>\n            <div class="hg-nav-phase-header"><span>Submission Phase</span></div>\n          </div>\n          <ul class="nav hg-nav-bottom-row">\n            <li id="hg-nav-step-submitting" class="hg-nav-step"><a href="',l=n.assessmentPath,l?s=l.call(t,{hash:{}}):(s=t.assessmentPath,s=typeof s===c?s():s),u+=d(s)+'/submissions" class="hg-internal">',l=n.incrementCounter,s=l?l.call(t,"step",{hash:{}}):p.call(t,"incrementCounter","step",{hash:{}}),u+=d(s)+'<span class="step">',l=n.step,l?s=l.call(t,{hash:{}}):(s=t.step,s=typeof s===c?s():s),u+=d(s)+'.</span><span>Do assignment</span><span class="hg-nav-step-status"><span class="hg-nav-step-status-todo icon-check-empty"></span><span class="hg-nav-step-status-other"></span></span></a></li>\n          </ul>\n        </li>\n        <li id="hg-nav-phase-grading" class="hg-nav-phase hg-nav-border-left hg-nav-border-right">\n          <div class="hg-nav-top-row">\n            <div class="progress">\n              <div class="bar"></div>\n            </div>\n            <div class="hg-asst-interval">\n              <div class="hg-asst-interval-part hg-asst-interval-open"><span data-livetimer-date-primitive="',s=t.assessment,s=null==s||s===!1?s:s.attributes,s=null==s||s===!1?s:s.gradingStartEffective,s=typeof s===c?s():s,u+=d(s)+'000" class="hg-date">',s=t.assessment,s=null==s||s===!1?s:s.attributes,s=null==s||s===!1?s:s.gradingStartString,s=typeof s===c?s():s,u+=d(s)+'</span></div>\n              <div class="hg-asst-interval-part hg-asst-interval-close"><span data-livetimer-date-primitive="',s=t.assessment,s=null==s||s===!1?s:s.attributes,s=null==s||s===!1?s:s.gradingDeadlineEffective,s=typeof s===c?s():s,u+=d(s)+'000" class="hg-date">',s=t.assessment,s=null==s||s===!1?s:s.attributes,s=null==s||s===!1?s:s.gradingDeadlineString,s=typeof s===c?s():s,u+=d(s)+'</span></div>\n            </div>\n            <div class="hg-asst-phase-reload"><a href="#" class="hg-internal hg-reload">Reload</a>&nbsp;to open</div>\n            <div class="hg-nav-phase-header"><span>Evaluation Phase</span></div>\n          </div>\n          <ul class="nav hg-nav-bottom-row">',l=n.ifPolicyHasEnabled,s=l?l.call(t,"training",{hash:{},inverse:h.noop,fn:h.program(1,o,a)}):p.call(t,"ifPolicyHasEnabled","training",{hash:{},inverse:h.noop,fn:h.program(1,o,a)}),(s||0===s)&&(u+=s),u+='\n            <li id="hg-nav-step-peerGrading" class="hg-nav-step"><a href="',l=n.assessmentPath,l?s=l.call(t,{hash:{}}):(s=t.assessmentPath,s=typeof s===c?s():s),u+=d(s)+'/peerGradingSets" class="hg-internal">',l=n.incrementCounter,s=l?l.call(t,"step",{hash:{}}):p.call(t,"incrementCounter","step",{hash:{}}),u+=d(s)+'<span class="step">',l=n.step,l?s=l.call(t,{hash:{}}):(s=t.step,s=typeof s===c?s():s),u+=d(s)+'.</span><span>Evaluate peers</span><span class="hg-nav-step-status"><span class="hg-nav-step-status-todo icon-check-empty"></span><span class="hg-nav-step-status-other"></span></span></a></li>',l=n.ifPolicyHasEnabled,s=l?l.call(t,"selfGrading",{hash:{},inverse:h.noop,fn:h.program(3,r,a)}):p.call(t,"ifPolicyHasEnabled","selfGrading",{hash:{},inverse:h.noop,fn:h.program(3,r,a)}),(s||0===s)&&(u+=s),u+='\n          </ul>\n        </li>\n        <li id="hg-nav-phase-results" class="hg-nav-phase hg-nav-border-left hg-nav-border-right">\n          <div class="hg-nav-top-row">\n            <div class="progress">\n              <div class="bar"></div>\n            </div>\n            <div class="hg-asst-interval">\n              <div class="hg-asst-interval-part hg-asst-interval-available"><span data-livetimer-date-primitive="',s=t.assessment,s=null==s||s===!1?s:s.attributes,s=null==s||s===!1?s:s.displayGradesTimeEffective,s=typeof s===c?s():s,u+=d(s)+'000" class="hg-date">',s=t.assessment,s=null==s||s===!1?s:s.attributes,s=null==s||s===!1?s:s.displayGradesTimeString,s=typeof s===c?s():s,u+=d(s)+'</span></div>\n            </div>\n            <div class="hg-asst-phase-reload"><a href="#" class="hg-internal hg-reload">Reload</a>&nbsp;to open</div>\n            <div class="hg-nav-phase-header"><span>Results Phase</span></div>\n          </div>\n          <ul class="nav hg-nav-bottom-row">\n            <li id="hg-nav-step-results" class="hg-nav-step"><a href="',l=n.assessmentPath,l?s=l.call(t,{hash:{}}):(s=t.assessmentPath,s=typeof s===c?s():s),u+=d(s)+'/results/mine" class="hg-internal">',l=n.incrementCounter,s=l?l.call(t,"step",{hash:{}}):p.call(t,"incrementCounter","step",{hash:{}}),u+=d(s)+'<span class="step">',l=n.step,l?s=l.call(t,{hash:{}}):(s=t.step,s=typeof s===c?s():s),u+=d(s)+'.</span><span>See results</span><span class="hg-nav-step-status"><span class="hg-nav-step-status-other"></span></span></a></li>\n          </ul>\n        </li>\n      </ul>\n    </div>\n  </div>\n</div>'}});
define('views/AssessmentNavigationView',["app/Assess","jquery","bootstrap_popover","underscore","backbone","marionette","jquery.livetimer","models/AssessmentAccess","models/AssessmentNavigationViewModel","views/BaseView","handlebars","templates/CreativeAssignmentNavView.hbs","templates/AssessmentNavigationView.hbs"],function(e,t,n,i,a,o,r,s,l,u,c,d,p){var h=function(e){if(!e)return"";var t=e.match(/-(\w+)$/);return t&&t.length>1?t[1]:""},f=function(e){return h(e)},m=function(e,t){e.attr("class","progress").addClass(t)},g=u.extend({id:"AssessmentNavigationView",template:function(){return c.template(e.adminMode&&"creative_assignment"===e.adminContext?d:p)},initialize:function(){var e=this;this.model.bind("change",this.render,this),this.model.bind("destroy",this.remove,this),this.model.get("assessmentAccess").on("update",function(){e.update()},this)},navigateToStep:function(e){this.update(),this.activateTab(e)},update:function(){var e=this,n=this.model.get("assessmentAccess");this.$(".hg-nav-step").each(function(){var i=t(this).attr("id"),a=h(i);if(n.isStepInaccessible(a))e.disableTab(i);else{var o="results"===a?!0:n.isStepCompleted(a);e.enableTab(i,o)}})},disableTab:function(e){var t=this.$("#"+e+" > a");if(t){t.addClass("disabled").attr("disabled","disabled");var n=this.$("#"+e+" span.hg-nav-step-status");n.removeClass("hg-nav-step-status-select-todo").addClass("hg-nav-step-status-select-other"),n.children(".hg-nav-step-status-other").removeClass("icon-check").addClass("icon-lock")}},enableTab:function(e,t){var n=this.$("#"+e+" > a");if(n.length){n.removeClass("disabled").removeAttr("disabled");var i=n.closest(".hg-nav-phase").find(".progress"),a=this.$("#"+e+" span.hg-nav-step-status");t?(a.removeClass("hg-nav-step-status-select-todo").addClass("hg-nav-step-status-select-other"),a.children(".hg-nav-step-status-other").removeClass("icon-lock").addClass("icon-check"),m(i,"progress-success")):(a.removeClass("hg-nav-step-status-select-other").addClass("hg-nav-step-status-select-todo"),i.hasClass("progress-success")&&m(i,"progress-default"))}},activateTab:function(e){this.$("li").each(function(){t(this).removeClass("active").removeClass("hg-phase-active").removeClass("hg-phase-relevant")}),this.$("#hg-nav-step-"+e).addClass("active").find(".hg-nav-step-status");var n=this.model.get("assessmentAccess"),i=n.get("currentPhase");this.$("li#hg-nav-phase-"+i).addClass("hg-phase-active").addClass("hg-phase-relevant");var a=i.match(/^pre-(.*)/);a&&this.$("li#hg-nav-phase-"+a[1]).addClass("hg-phase-relevant")},tabPopoverInfo:function(t,n,i,a,o,r){var l=this,u={},c=l.model.get("assessment"),d=c.isIncompletePeerGradingPenaltyEnabled(),p=c.isDisplayGradeEnabled(),h=l.model.get("assessmentAccess"),f=h.get("currentPhase"),m=s.phaseOrder(f),g=!t.hasClass("disabled"),v=h.isStepCompleted(n);if(g)if(m>a)u.title="Page viewable only",u.content="",v||(u.content+="<p>Sorry, you cannot "+s.STEPS[n].verbalPhrase+".</p>"),u.content+="<p>The "+s.PHASES[i].text+" phase "+r.attr("title")+".</p>";else if(e.expect(a===m,"An upcoming step should not have its tab enabled."),"results"===n);else if(h.isStepCompleted(n))u.title="Well done",u.content="You have completed this step.";else{u={title:"Your tasks",content:"<p>"};var b=" in order to receive full credit for this assignment.</p></p><p>If you do not, your grade will be penalized by 20%",y=!d,w=!d;switch(n){case"submitting":u.content="Remember to do your assignment for it to be assessed by your peers and, in turn, for you to evaluate your peers.";break;case"training":u.content="Remember to complete the training to be permitted to evaluate the work of your peers.";break;case"peerGrading":u.content="Remember to complete the required evaluations for your peers"+(!y&&p?b:"")+".";break;case"selfGrading":u.content="Remember, you "+(w?"should":"must")+" evaluate your own work"+(!w&&p?b:"")+".";break;default:return e.expect(!1,"This step is not recognized. Cannot fill popover content."),u.content="Remember to do all your required tasks to get full credit.",void 0}u.content+="</p>"}else if(u.title="Page not available",u.content="<p>Sorry, you cannot "+s.STEPS[n].verbalPhrase,m===a){u.content+=".</p>";var x=c.blockerStepFor(n),k=s.STEPS[x].phase;e.expect(x&&k,"Can't figure out why user has no access to this tab.")&&(u.content+=m>s.phaseOrder(k)?"<p>It appears that you did not finish "+s.STEPS[x].gerundPhrase+".</p>":"<p>You must first finish "+s.STEPS[x].gerundPhrase+".</p>")}else a>m?(u.content+=" yet.</p>",u.content+="results"===i?"<p>You must wait until "+s.PHASES[i].text+" are "+o.attr("title")+".</p>":"<p>You must wait until the "+s.PHASES[i].text+" phase "+o.attr("title")+".</p>"):m>a&&(u.content+=" anymore.</p>",u.content+="<p>The "+s.PHASES[i].text+" phase "+r.attr("title")+".</p>");return u},bindTabEventHandlers:function(){var e=this;this.$("li a").on("click",function(e){return t(this).hasClass("disabled")?(e.preventDefault(),!1):!0}),this.$("li.hg-nav-step > a").each(function(){var n=t(this),i=n.parent(),a=h(i.attr("id")),o=i.closest(".hg-nav-phase"),r=f(o.attr("id")),l=s.phaseOrder(r),u=o.find(".hg-asst-interval-open      > .hg-date, .hg-asst-interval-available > .hg-date"),c=o.find(".hg-asst-interval-close    > .hg-date");n.popover({placement:"bottom",animation:!1,delay:200,title:function(){return e.tabPopoverInfo(n,a,r,l,u,c).title},content:function(){return e.tabPopoverInfo(n,a,r,l,u,c).content}})})},render:function(){this.model.get("assessmentAccess"),a.Marionette.ItemView.prototype.render.call(this),this.bindTabEventHandlers(),this.update(),this.renderLiveTimers()},renderLiveTimers:function(){var e="ddd DD MMM hh:mm a";this.$el.find(".hg-asst-interval-open .hg-date").livetimer({absolute:{pastFormat:"opened %s",futureFormat:"open %s",momentReformat:e},relative:{pastFormat:"opened %s ago",futureFormat:"open in %s",style:"binary-concise"},title:{pastFormat:"opened on %1$s\n(%2$s ago)",futureFormat:"opens on %1$s\n(in %2$s)"},display:"relative"}),this.$el.find(".hg-asst-interval-close .hg-date").livetimer({absolute:{pastFormat:"closed %s",futureFormat:"due %s",momentReformat:e},relative:{pastFormat:"closed %s ago",futureFormat:"due in %s",style:"binary-concise"},title:{pastFormat:"closed on %1$s\n(%2$s ago)",futureFormat:"is due on %1$s\n(in %2$s)"},display:"relative"}),this.$el.find(".hg-asst-interval-available .hg-date").livetimer({absolute:{pastFormat:"available %s",futureFormat:"available %s",momentReformat:e},relative:{pastFormat:"",futureFormat:"in %s",style:"binary-concise"},title:{pastFormat:"available since %1$s\n(%2$s ago)",futureFormat:"available %1$s\n(in %2$s)"},display:"relative"}),this.$el.find(".hg-nav-phase").each(function(){var e,n,i,a=t(this),o=a.find(".progress"),r=o.children(".bar"),s=a.find(".hg-asst-interval-open      > :coursera-livetimer, .hg-asst-interval-available > :coursera-livetimer"),l=a.find(".hg-asst-interval-close    > :coursera-livetimer"),u=s.livetimer("getDate"),c=l.livetimer("getDate");s.length&&l.length&&(i=c.valueOf()-u.valueOf());var d=function(){var t=!s.length||s.livetimer("isPast"),i=l.length&&l.livetimer("isPast");t?(e=i?"past":"current",l.length?(s.parent().hide(),l.parent().show()):(s.parent().show(),l.parent().hide())):(e="future",s.parent().show(),l.parent().hide()),a.attr("data-hg-date-status",e);var o=new Date;if(s.length){var r=o>u-36e5&&u>=o;s.attr("data-hg-date-status",r?"soon":"")}if(l.length){var d=o>c-36e5&&c>=o,p=o>c;n=p?"past":d?"soon":"",l.attr("data-hg-date-status",n)}};d();var p=function(){var t,a=new Date;t=i?"past"===e?"100%":"current"===e?5*Math.max(1,Math.floor(20*(Math.min(a,c)-u)/i))+"%":"0":a>=u?"100%":"0",o.hasClass("progress-success")||m(o,"soon"===n?"progress-warning":"past"===n?"progress-danger":"progress-info"),r.css("width",t)};p(o,r),s.livetimer({hasPassed:function(){d()}}),l.livetimer({hasPassed:function(){d()}}),l.livetimer({tick:function(){p(o,r)}})})}});return g});
define('models/Assessment',["app/Assess","lib/Util","jquery","underscore","backbone","models/AssessmentAccess"],function(e,t,n,i,a,o){var r=a.Model.extend({course:null,getBaseUrl:function(){return this.course?this.course.getBaseUrl():""},url:function(){e.assert(this.course,"this.course undefined on assessment "+this.id);var t=this.getBaseUrl()+"assessments";return this.isNew()?t:t+("/"===t.charAt(t.length-1)?"":"/")+this.id},getPolicy:function(){return this.get("policy")},isStepEnabled:function(e){var n=this.getPolicy();return n?t.getElement(n[e],"enabled",!0):!0},isResubmitAllowed:function(){var e=this.getPolicy();return e?t.getElement(e.submitting,"allowResubmit",!0):!0},isSharingEnabled:function(){var e=this.getPolicy();return e?t.getElement(e.sharing,"enabled",!1):!1},allowsExclusionFromCirculation:function(){var e=this.getPolicy();return e?e.allowExclusionFromCirculation!==!1:!0},isDisplayGradeEnabled:function(){var e=this.getPolicy();return e?e.displayGrade!==!1:!0},isIncompletePeerGradingPenaltyEnabled:function(){var e=this.getPolicy();return e?t.getElement(e.incompletePeerGradingPenalty,"enabled",!0):!0},targetGradingsPerUser:function(){var e=this.getPolicy();return e?e.targetGradingsPerUser:0},blockerStepFor:function(e){var t=o.STEPS[e].blockerStep;return"training"!==t||this.isStepEnabled("training")?"selfGrading"!==t||this.isStepEnabled("selfGrading")||(t="peerGrading"):t="submitting",t}});return r});
define('models/OverallEvaluation',["app/Assess","jquery","underscore","backbone","marionette","models/Submission"],function(e,t,n,i){var a=i.DeepModel.extend({submission:null,getBaseUrl:function(){return e.API_BASE_URL},url:function(){return this.isNew()?(e.assert(this.submission,"this.submission undefined on evaluation "+this.id),this.submission.url()+"/overallEvaluation"):void 0}});return a});
define('templates/SubmissionShowLayout.hbs',[],function(){return function(e,t,n){return n=n||e.helpers,'\n<div id="assessmentContainer" aria-live="polite" class="container-fluid">\n  <div id="assessmentMessages"></div>\n  <div id="submissionShowRegion" class="contentRegion"></div>\n</div>'}});
define('views/SubmissionShowLayout',["app/Assess","underscore","backbone","marionette","handlebars","models/Submission","templates/SubmissionShowLayout.hbs"],function(e,t,n,i,a,o,r){var s=n.Marionette.Layout.extend({template:function(){return a.template(r)},tagName:"div",id:"SubmissionShowLayout",regions:{contentRegion:"#submissionShowRegion"}});return s});
// Backbone.ModelBinding v0.5.0
//
// Copyright (C)2011 Derick Bailey, Muted Solutions, LLC
// Distributed Under MIT Liscene
//
// Documentation and Full Licence Availabe at:
// http://github.com/derickbailey/backbone.modelbinding
//
// ----------------------------
// Backbone.ModelBinding
// ----------------------------
;(function(root){

var modelbinding = (function(Backbone, _, $) {
  var modelBinding = {
    version: "0.5.0",

    bind: function(view, options){
      view.modelBinder = new ModelBinder(view, options);
      view.modelBinder.bind();
    },

    unbind: function(view){
      if (view.modelBinder){
        view.modelBinder.unbind()
      }
    }
  };

  var ModelBinder = function(view, options){
    this.config = new modelBinding.Configuration(options);
    this.modelBindings = [];
    this.elementBindings = [];

    this.bind = function(){
      var conventions = modelBinding.Conventions;
      for (var conventionName in conventions){
        if (conventions.hasOwnProperty(conventionName)){
          var conventionElement = conventions[conventionName];
          var handler = conventionElement.handler;
          var conventionSelector = conventionElement.selector;
          handler.bind.call(this, conventionSelector, view, view.model, this.config);
        }
      }
    };

    this.unbind = function(){
      // unbind the html element bindings
      _.each(this.elementBindings, function(binding){
        binding.element.unbind(binding.eventName, binding.callback);
      });

      // unbind the model bindings
      _.each(this.modelBindings, function(binding){
        binding.model.unbind(binding.eventName, binding.callback);
      });
    };

    this.registerModelBinding = function(model, attrName, callback){
      // bind the model changes to the form elements
      var eventName = "change:" + attrName;
      model.bind(eventName, callback);
      this.modelBindings.push({model: model, eventName: eventName, callback: callback});
    };

    this.registerDataBinding = function(model, eventName, callback){
      // bind the model changes to the elements
      
      model.bind(eventName, callback);
      this.modelBindings.push({model: model, eventName: eventName, callback: callback});
    };

    this.registerElementBinding = function(element, callback){
      // bind the form changes to the model
      element.bind("change", callback);
      this.elementBindings.push({element: element, eventName: "change", callback: callback});
    };
  };

  // ----------------------------
  // Model Binding Configuration
  // ----------------------------
  modelBinding.Configuration = function(options){
    this.bindingAttrConfig = {};

    _.extend(this.bindingAttrConfig, 
      modelBinding.Configuration.bindindAttrConfig,
      options
    );

    if (this.bindingAttrConfig.all){
      var attr = this.bindingAttrConfig.all;
      delete this.bindingAttrConfig.all;
      for (var inputType in this.bindingAttrConfig){
        if (this.bindingAttrConfig.hasOwnProperty(inputType)){
          this.bindingAttrConfig[inputType] = attr;
        }
      }
    }

    this.getBindingAttr = function(type){ 
      return this.bindingAttrConfig[type]; 
    };

    this.getBindingValue = function(element, type){
      var bindingAttr = this.getBindingAttr(type);
      return element.attr(bindingAttr);
    };

  };

  modelBinding.Configuration.bindindAttrConfig = {
    text: "id",
    textarea: "id",
    password: "id",
    radio: "name",
    checkbox: "id",
    select: "id",
    number: "id",
    range: "id",
    tel: "id",
    search: "id",
    url: "id",
    email: "id"
  };

  modelBinding.Configuration.store = function(){
    modelBinding.Configuration.originalConfig = _.clone(modelBinding.Configuration.bindindAttrConfig);
  };

  modelBinding.Configuration.restore = function(){
    modelBinding.Configuration.bindindAttrConfig = modelBinding.Configuration.originalConfig;
  };

  modelBinding.Configuration.configureBindingAttributes = function(options){
    if (options.all){
      this.configureAllBindingAttributes(options.all);
      delete options.all;
    }
    _.extend(modelBinding.Configuration.bindindAttrConfig, options);
  };

  modelBinding.Configuration.configureAllBindingAttributes = function(attribute){
    var config = modelBinding.Configuration.bindindAttrConfig;
    config.text = attribute;
    config.textarea = attribute;
    config.password = attribute;
    config.radio = attribute;
    config.checkbox = attribute;
    config.select = attribute;
    config.number = attribute;
    config.range = attribute;
    config.tel = attribute;
    config.search = attribute;
    config.url = attribute;
    config.email = attribute;
  };

  // ----------------------------
  // Text, Textarea, and Password Bi-Directional Binding Methods
  // ----------------------------
  var StandardBinding = (function(Backbone){
    var methods = {};

    var _getElementType = function(element) {
      var type = element[0].tagName.toLowerCase();
      if (type == "input"){
        type = element.attr("type");
        if (type == undefined || type == ''){
          type = 'text';
        }
      }
      return type;
    };

    methods.bind = function(selector, view, model, config){
      var modelBinder = this;

      view.$(selector).each(function(index){
        var element = view.$(this);
        var elementType = _getElementType(element);
        var attribute_name = config.getBindingValue(element, elementType);

        // huy 2012-04-14 Relax the requirement that input fields have an id/name
        // For example <textarea data-bind="modelAttr" /> should be useful
        if (! attribute_name)
          return;

        var modelChange = function(changed_model, val){ element.val(val); };

        var setModelValue = function(attr_name, value){
          var data = {};
          data[attr_name] = value;
          model.set(data);
        };

        var elementChange = function(ev){
          setModelValue(attribute_name, view.$(ev.target).val());
        };

        modelBinder.registerModelBinding(model, attribute_name, modelChange);
        modelBinder.registerElementBinding(element, elementChange);

        // set the default value on the form, from the model
        var attr_value = model.get(attribute_name);
        if (typeof attr_value !== "undefined" && attr_value !== null) {
          element.val(attr_value);
        } else {
          var elVal = element.val();
          if (elVal){
            setModelValue(attribute_name, elVal);
          }
        }
      });
    };

    return methods;
  })(Backbone);

  // ----------------------------
  // Select Box Bi-Directional Binding Methods
  // ----------------------------
  var SelectBoxBinding = (function(Backbone){
    var methods = {};

    methods.bind = function(selector, view, model, config){
      var modelBinder = this;

      view.$(selector).each(function(index){
        var element = view.$(this);
        var attribute_name = config.getBindingValue(element, 'select');

        var modelChange = function(changed_model, val){ element.val(val); };

        var setModelValue = function(attr, val, text){
          var data = {};
          data[attr] = val;
          data[attr + "_text"] = text;
          model.set(data);
        };

        var elementChange = function(ev){
          var targetEl = view.$(ev.target);
          var value = targetEl.val();
          var text = targetEl.find(":selected").text();
          setModelValue(attribute_name, value, text);
        };

        modelBinder.registerModelBinding(model, attribute_name, modelChange);
        modelBinder.registerElementBinding(element, elementChange);

        // set the default value on the form, from the model
        var attr_value = model.get(attribute_name);
        if (typeof attr_value !== "undefined" && attr_value !== null) {
          element.val(attr_value);
        } 

        // set the model to the form's value if there is no model value
        if (element.val() != attr_value) {
          var value = element.val();
          var text = element.find(":selected").text();
          setModelValue(attribute_name, value, text);
        }
      });
    };

    return methods;
  })(Backbone);

  // ----------------------------
  // Radio Button Group Bi-Directional Binding Methods
  // ----------------------------
  var RadioGroupBinding = (function(Backbone){
    var methods = {};

    methods.bind = function(selector, view, model, config){
      var modelBinder = this;

      var foundElements = [];
      view.$(selector).each(function(index){
        var element = view.$(this);

        var group_name = config.getBindingValue(element, 'radio');
        if (!foundElements[group_name]) {
          foundElements[group_name] = true;
          var bindingAttr = config.getBindingAttr('radio');

          var modelChange = function(model, val){
            var value_selector = "input[type=radio][" + bindingAttr + "='" + group_name + "'][value='" + val + "']";
            view.$(value_selector).attr("checked", "checked");
          };
          modelBinder.registerModelBinding(model, group_name, modelChange);

          var setModelValue = function(attr, val){
            var data = {};
            data[attr] = val;
            model.set(data);
          };

          // bind the form changes to the model
          var elementChange = function(ev){
            var element = view.$(ev.currentTarget);
            if (element.is(":checked")){
              setModelValue(group_name, element.val());
            }
          };

          var group_selector = "input[type=radio][" + bindingAttr + "='" + group_name + "']";
          view.$(group_selector).each(function(){
            var groupEl = $(this);
            modelBinder.registerElementBinding(groupEl, elementChange);
          });

          var attr_value = model.get(group_name);
          if (typeof attr_value !== "undefined" && attr_value !== null) {
            // set the default value on the form, from the model
            var value_selector = "input[type=radio][" + bindingAttr + "='" + group_name + "'][value='" + attr_value + "']";
            view.$(value_selector).attr("checked", "checked");
          } else {
            // set the model to the currently selected radio button
            var value_selector = "input[type=radio][" + bindingAttr + "='" + group_name + "']:checked";
            var value = view.$(value_selector).val();
            setModelValue(group_name, value);
          }
        }
      });
    };

    return methods;
  })(Backbone);

  // ----------------------------
  // Checkbox Bi-Directional Binding Methods
  // ----------------------------
  var CheckboxBinding = (function(Backbone){
    var methods = {};

    methods.bind = function(selector, view, model, config){
      var modelBinder = this;

      view.$(selector).each(function(index){
        var element = view.$(this);
        var bindingAttr = config.getBindingAttr('checkbox');
        var attribute_name = config.getBindingValue(element, 'checkbox');

        var modelChange = function(model, val){
          if (val){
            element.attr("checked", "checked");
          }
          else{
            element.removeAttr("checked");
          }
        };

        var setModelValue = function(attr_name, value){
          var data = {};
          data[attr_name] = value;
          model.set(data);
        };

        var elementChange = function(ev){
          var changedElement = view.$(ev.target);
          var checked = changedElement.is(":checked")? true : false;
          setModelValue(attribute_name, checked);
        };

        modelBinder.registerModelBinding(model, attribute_name, modelChange);
        modelBinder.registerElementBinding(element, elementChange);

        var attr_exists = model.attributes.hasOwnProperty(attribute_name);
        if (attr_exists) {
          // set the default value on the form, from the model
          var attr_value = model.get(attribute_name);
          if (typeof attr_value !== "undefined" && attr_value !== null && attr_value != false) {
            element.attr("checked", "checked");
          }
          else{
            element.removeAttr("checked");
          }
        } else {
          // bind the form's value to the model
          var checked = element.is(":checked")? true : false;
          setModelValue(attribute_name, checked);
        }
      });
    };

    return methods;
  })(Backbone);

  // ----------------------------
  // Data-Bind Binding Methods
  // ----------------------------
  var DataBindBinding = (function(Backbone, _, $){
    var dataBindSubstConfig = {
      "default": ""
    };

    modelBinding.Configuration.dataBindSubst = function(config){
      this.storeDataBindSubstConfig();
      _.extend(dataBindSubstConfig, config);
    };

    modelBinding.Configuration.storeDataBindSubstConfig = function(){
      modelBinding.Configuration._dataBindSubstConfig = _.clone(dataBindSubstConfig);
    };

    modelBinding.Configuration.restoreDataBindSubstConfig = function(){
      if (modelBinding.Configuration._dataBindSubstConfig){
        dataBindSubstConfig = modelBinding.Configuration._dataBindSubstConfig;
        delete modelBinding.Configuration._dataBindSubstConfig;
      }
    };

    modelBinding.Configuration.getDataBindSubst = function(elementType, value){
      var returnValue = value;
      if (value === undefined){
        if (dataBindSubstConfig.hasOwnProperty(elementType)){
          returnValue = dataBindSubstConfig[elementType];
        } else {
          returnValue = dataBindSubstConfig["default"];
        }
      }
      return returnValue;
    };

    var setOnElement = function(element, attr, val){
      var valBefore = val;
      val = modelBinding.Configuration.getDataBindSubst(attr, val);
      switch(attr){
        case "html":
          element.html(val);
          break;
        case "text":
          element.text(val);
          break;
        case "enabled":
          element.attr("disabled", !val);
          break;
        case "displayed":
          element[val? "show" : "hide"]();
          break;
        case "hidden":
          element[val? "hide" : "show"]();
          break;
        default:
          element.attr(attr, val);
      }
    };

    var splitBindingAttr = function(element)
    {
      var dataBindConfigList = [];
      var dataBindAttributeName = modelBinding.Conventions.databind.selector.replace(/^(.*\[)([^\]]*)(].*)/g, '$2');
      var databindList = element.attr(dataBindAttributeName).split(";");
      _.each(databindList, function(attrbind){
        var databind = $.trim(attrbind).split(" ");

        // make the default special case "text" if none specified
        if( databind.length == 1 ) databind.unshift("text");

        dataBindConfigList.push({
          elementAttr: databind[0],
          modelAttr: databind[1]
        });
      });
      return dataBindConfigList;
    };

    var getEventConfiguration = function(element, databind){
      var config = {};
      var eventName = databind.modelAttr;
      var index = eventName.indexOf("event:");

      if (index == 0) {
        // "event:foo" binding
        config.name = eventName.substr(6);
        config.callback = function(val){
          setOnElement(element, databind.elementAttr, val);
        };
      } else {
        // standard model attribute binding
        config.name = "change:" + eventName;
        config.callback = function(model, val){
          setOnElement(element, databind.elementAttr, val);
        };
      }

      return config;
    }
    var methods = {};

    methods.bind = function(selector, view, model, config){
      var modelBinder = this;

      view.$(selector).each(function(index){
        var element = view.$(this);
        var databindList = splitBindingAttr(element);

        _.each(databindList, function(databind){
          var eventConfig = getEventConfiguration(element, databind);
          modelBinder.registerDataBinding(model, eventConfig.name, eventConfig.callback);
          // set default on data-bind element
          setOnElement(element, databind.elementAttr, model.get(databind.modelAttr));
        });

      });
    };

    return methods;
  })(Backbone, _, $);


  // ----------------------------
  // Binding Conventions
  // ----------------------------
  modelBinding.Conventions = {
    text: {selector: "input:text", handler: StandardBinding},
    textarea: {selector: "textarea", handler: StandardBinding},
    password: {selector: "input:password", handler: StandardBinding},
    radio: {selector: "input:radio", handler: RadioGroupBinding},
    checkbox: {selector: "input:checkbox", handler: CheckboxBinding},
    select: {selector: "select", handler: SelectBoxBinding},
    databind: { selector: "*[data-bind]", handler: DataBindBinding},
    // HTML5 input
    number: {selector: "input[type=number]", handler: StandardBinding},
    range: {selector: "input[type=range]", handler: StandardBinding},
    tel: {selector: "input[type=tel]", handler: StandardBinding},
    search: {selector: "input[type=search]", handler: StandardBinding},
    url: {selector: "input[type=url]", handler: StandardBinding},
    email: {selector: "input[type=email]", handler: StandardBinding}
  };

  return modelBinding;
});

// Backbone.Modelbinding AMD wrapper with namespace fallback
if (typeof define === 'function' && define.amd) {
    // AMD support
    define('modelbinding',[
      'backbone',    // use Backbone 0.5.3-optamd3 branch (https://github.com/jrburke/backbone/tree/optamd3)
      'underscore',  // AMD supported
      'jquery'       // AMD supported
      ], function (Backbone, _, jQuery) {
        return modelbinding(Backbone, _, jQuery);
      });
} else {
    // No AMD, use Backbone namespace
    root.Backbone = Backbone || {};
    root.Backbone.ModelBinding = modelbinding(Backbone, _, jQuery);
}

})(this);

(function(){var e=function(e,t,i){var n=0,a=1,o={defaults:{"bind.open":"click","bind.close":"click","bind.esc":!0,"attribute.open":"data-modal","attribute.close":"data-modal-close","attribute.iframe":"data-modal-iframe","animate.modal.open":null,"animate.modal.close":null,"animate.modal.duration":250,"animate.overlay.open":null,"animate.overlay.close":null,"animate.overlay.duration":250,"overlay.show":!0,"overlay.class":"overlay","close.selector":!1,"close.esc":!0,"z.index":9999,"position.top":"50%","position.left":"50%",position:"fixed","iframe.autoclose":!0},$overlay:null,prevScroll:null,prevModal:null,getModal:function(t,i){var n=e(t).data("modal.me");return n&&n.constructor==r.prototype.constructor?i?n.customize(i):n:null},makeModal:function(t,i){var n=e(t),a=o.getModal(n);return a||(a=new r(n,i),n.data("modal.me",a)),a},setOverlayHeight:function(){e(window).height()<e(document).height()?o.$overlay.css({height:e(document).height()+"px"}):o.$overlay.css({height:"100%"})},observeKeyPress:function(e){(27==e.keyCode||27==e.DOM_VK_ESCAPE&&0===e.which)&&this.options["bind.esc"]&&this.close()},open:function(){if("fixed"!=this.options.position&&(o.prevScroll={top:e(document).scrollTop(),left:e(document).scrollLeft()},window.scrollTo(0,0)),this.$iframe){var t=e(this.anchor).attr(this.options["attribute.iframe"]);this.$iframe.attr("src",t),this.$iframe.focus()}else this.$el.focus();this.state=a,this.trigger("open")},close:function(){var e=this.$el.find("iframe");this.$el.off(".modal").hide(),this.options["iframe.autoclose"]&&e.size()&&e.attr({src:"about:blank"}),o.prevScroll&&(window.scrollTo(o.prevScroll.left,o.prevScroll.top),o.prevScroll=null),this.anchor=null,this.$parent.append(this.$el),this.state=n,this.trigger("close")},readDataAttributes:function(e,t,i){var n={};for(var a in i){var o=e.attr(t+a.replace(/\./g,"-"));n[a]=void 0===o||0===o.length?i[a]:o}return n}},r=function(t,i){this.$el=e(t),this.state=n,this.$parent=this.$el.parent(),this.customize(i)};r.prototype.customize=function(e){return this.options=i.extend({},o.readDataAttributes(this.$el,"data-modal-",o.defaults),e),this},r.prototype.open=function(){var t,a=this;if(this.anchor){var r=e(this.anchor);this.$iframe=this.$el.find("iframe"),t=r.attr(this.options["attribute.iframe"]),/^https?:\/\/|^\/|^\.\.\//.test(t)&&(this.$iframe.size()&&this.$iframe.attr("src")==t||(this.$iframe.attr("src","about:blank").remove(),this.$iframe=e("<iframe>").css({height:"100%",width:"100%"}).attr({scrolling:"no",frameborder:0}),this.$el.append(this.$iframe),this.state!=n&&this.$iframe.attr("src",t)))}return this.state==n?(this.options["overlay.show"]&&(o.$overlay&&"none"!=o.$overlay.css("display")&&o.$overlay.hasClass(this.options["overlay.class"])?this.$overlay=o.$overlay:(o.$overlay&&o.$overlay.off(".modal").hide().remove(),this.$overlay=o.$overlay=e("<div>").addClass(this.options["overlay.class"]).hide(),this.$overlay.css({position:"fixed",width:"100%",top:0,left:0,right:0,bottom:0,zIndex:this.options["z.index"]++}),e("body").append(this.$overlay)),o.setOverlayHeight(),this.reposition(),this.options["animate.overlay.open"]?this.$overlay.animate(this.options["animate.overlay.open"],{duration:this.options["animate.overlay.duration"]}):this.$overlay.show(),this.$overlay.data("modal",this)),this.trigger("opening"),("fixed"!=this.options.position||0===this.$el.closest("html").length)&&this.$el.appendTo("body"),this.reposition(),this.$el.show(),this.options["animate.modal.open"]?this.$el.animate(this.options["animate.modal.open"],{duration:this.options["animate.modal.duration"],complete:function(){o.open.call(a)}}):o.open.call(this),e(window).on("resize.modal",i.bind(o.setOverlayHeight,a)).on("resize.modal",i.bind(a.reposition,a)).on("scroll.modal",i.bind(a.reposition,a)).on("keyup.modal",i.bind(o.observeKeyPress,a)),this.options["bind.close"]&&this.$overlay.on(this.options["bind.close"]+".modal",function(){a.close()}),this.options["attribute.close"]&&this.$el.on(this.options["bind.close"]+".modal","["+this.options["attribute.close"]+"]",function(){"disabled"!=a.$el.attr("disabled")&&a.close()}),this):void 0},r.prototype.reposition=function(){var e=this.options["position.left"],t=this.options["position.top"];return e&&this.$el.css({position:this.options.position,left:e,marginLeft:/%/.test(e)?-1*(this.$el.outerWidth()/2):0,zIndex:this.options["z.index"]++}),t&&this.$el.css({position:this.options.position,top:t,marginTop:/%/.test(t)?-1*(this.$el.outerHeight()/2):0,zIndex:this.options["z.index"]++}),this},r.prototype.close=function(){var t=this;if(this.state==a)return this.$el.off(".modal"),e(window).off(".modal"),this.options["overlay.show"]&&this.$overlay&&(this.$overlay.off(".modal"),this.options["animate.overlay.close"]?this.$overlay.animate(this.options["animate.overlay.close"],{duration:this.options["animate.overlay.duration"],complete:function(){this.$overlay.hide().remove()}}):this.$overlay.hide().remove()),this.trigger("closing"),this.options["animate.modal.close"]?this.$el.animate(this.options["animate.modal.close"],{duration:this.options["animate.modal.duration"],complete:function(){o.close.call(t)}}):o.close.call(this),this},i.extend(r.prototype,t.Events);var s=function(){return o.getModal.apply(null,arguments)||o.makeModal.apply(this,arguments)};return s.start=function(t,n){var a=e(t),r=i.extend({},o.defaults,n);a.on(r["bind.open"]+".modal","["+r["attribute.open"]+"]",function(t){var n=e(this),s=n.attr(r["attribute.open"]),l=a.find(s);r=i.extend({},r,o.readDataAttributes(l,"data-modal-",o.defaults));var u=o.getModal(l,r)||o.makeModal(l,r);!/^https?:\/\/|^\/|^\.\.\//.test(n.attr("href"))||t.ctrlKey||t.metaKey||t.preventDefault(),u.anchor=this,o.prevModal=l[0],u.open()})},s.stop=function(t){var i=e(t);i.unbind(".modal"),o.prevModal&&r(o.prevModal).close()},s.start("body"),s};"function"==typeof define&&define.amd?define('modals',["jquery","backbone","underscore"],function(t,i,n){return e(t,i,n)}):"undefined"!=typeof window&&"undefined"==typeof ender&&(window.Modal=e(window.$,window.Backbone,window._))})();
(function(){var e=function(e,t){var n={defaults:{type:"quiz",submissionid:0,url:""},makeModal:function(e){e.addClass("modal");var n=new t(e,{"overlay.class":"coursera-signature-modal-overlay-darker","bind.close":!1,"bind.esc":!1});return n}},i=function(t,i){this.$el=e(t),this.options=e.extend({},n.defaults,"object"==typeof i&&i)};return i.prototype.open=function(){var t=this;return t.modal=n.makeModal(t.$el),t.modal.open(),t.$iframe=e("<iframe>"),t.$iframe.attr("src",t.options.url+"?submission_id="+t.options.submissionid+"&type="+t.options.type),t.$el.append(t.$iframe),t.$iframe.height("382px"),t.modal.reposition(),t.$iframe.load(function(){var n=t.$iframe.contents(),i=n.find("html").find("body");e("body").on("change.signature",function(){t.$iframe.height(i.outerHeight()),t.modal.reposition()}),e("body").on("close.signature",function(){t.$iframe.attr("src","about:blank"),t.$iframe.remove(),t.modal.close(),t.deferred.resolve()}),t.$iframe.height(i.outerHeight()),t.modal.reposition()}),t.deferred=e.Deferred(),t.deferred.promise()},i};"function"==typeof define&&define.amd?define('SignatureAuthModal',["jquery","modals"],function(t,n){return e(t,n)}):"undefined"!=typeof window&&"undefined"==typeof ender&&(window.SignatureAuthModal=e(window.$,window.Modal))})();
/*
* Copyright (c) 2011 Simon Hibbard
* 
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:

* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE. 
*/

/*
* Version: V1.3.2
* Release: 01-03-2010
* Based on jQuery 1.5.0
*/

(function ($) {
    var divgrowid = 0;
    $.fn.divgrow = function (options) {
        var options = $.extend({}, { initialHeight: 100, moreText: "+ Show More", lessText: "- Show Less", speed: 1000, showBrackets: true }, options);

        return this.each(function () {
            divgrowid++;

            obj = $(this);

            var fullHeight = obj.height() + 10;

            obj.css('height', options.initialHeight).css('overflow', 'hidden');
            obj.addClass('divgrow-wrapper');
            if (options.showBrackets) {
                obj.after('<p class="divgrow-brackets">[&hellip;]</p><a href="#" class="divgrow-showmore' + " divgrow-obj-" + divgrowid + '"' + '></a>');
            }
            else {
                obj.after('<a href="#" class="divgrow-showmore' + " divgrow-obj-" + divgrowid + '"' + '></a>');
            }
            $("a.divgrow-showmore").html(options.moreText);

            $("." + "divgrow-obj-" + divgrowid).toggle(function () {
                //alert(obj.attr('class'));
                // Set the height from the elements rel value
                //var height = $(this).prevAll("div:first").attr('rel');

                $(this).prevAll(".divgrow-wrapper:first").animate({ height: fullHeight + "px" }, options.speed, function () { // Animation complete.

                    // 2012-06-13 huy@coursera.org Sometimes the fullHeight is wrong; e.g., when
                    // a Youtube video or images load a few hundred milliseconds later.
                    // So this resets the height, after the animation is done. (Could make the
                    // animation jerky at the end)
                    $(this).css('height', '');

                    // Hide the overlay text when expanded, change the link text
                    if (options.showBrackets) {
                        $(this).nextAll("p.divgrow-brackets:first").fadeOut();
                    }
                    $(this).nextAll("a.divgrow-showmore:first").html(options.lessText);

                });


            }, function () {

                $(this).prevAll(".divgrow-wrapper:first").stop(true, false).animate({ height: options.initialHeight }, options.speed, function () { // Animation complete.

                    // show the overlay text while closed, change the link text
                    if (options.showBrackets) {
                        $(this).nextAll("p.divgrow-brackets:first").stop(true, false).fadeIn();
                    }
                    $(this).nextAll("a.divgrow-showmore:first").stop(true, false).html(options.moreText);

                });
            });

        });
    };
})(jQuery);






define("divgrow", ["jquery"], function(){});

/* ========================================================
 * bootstrap-tab.js v2.0.2
 * http://twitter.github.com/bootstrap/javascript.html#tabs
 * ========================================================
 * Copyright 2012 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ======================================================== */


!function( $ ){

  "use strict"

 /* TAB CLASS DEFINITION
  * ==================== */

  var Tab = function ( element ) {
    this.element = $(element)
  }

  Tab.prototype = {

    constructor: Tab

  , show: function () {
      var $this = this.element
        , $ul = $this.closest('ul:not(.dropdown-menu)')
        , selector = $this.attr('data-target')
        , previous
        , $target

      if (!selector) {
        selector = $this.attr('href')
        selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
      }

      if ( $this.parent('li').hasClass('active') ) return

      previous = $ul.find('.active a').last()[0]

      $this.trigger({
        type: 'show'
      , relatedTarget: previous
      })

      $target = $(selector)

      this.activate($this.parent('li'), $ul)
      this.activate($target, $target.parent(), function () {
        $this.trigger({
          type: 'shown'
        , relatedTarget: previous
        })
      })
    }

  , activate: function ( element, container, callback) {
      var $active = container.find('> .active')
        , transition = callback
            && $.support.transition
            && $active.hasClass('fade')

      function next() {
        $active
          .removeClass('active')
          .find('> .dropdown-menu > .active')
          .removeClass('active')

        element.addClass('active')

        if (transition) {
          element[0].offsetWidth // reflow for transition
          element.addClass('in')
        } else {
          element.removeClass('fade')
        }

        if ( element.parent('.dropdown-menu') ) {
          element.closest('li.dropdown').addClass('active')
        }

        callback && callback()
      }

      transition ?
        $active.one($.support.transition.end, next) :
        next()

      $active.removeClass('in')
    }
  }


 /* TAB PLUGIN DEFINITION
  * ===================== */

  $.fn.tab = function ( option ) {
    return this.each(function () {
      var $this = $(this)
        , data = $this.data('tab')
      if (!data) $this.data('tab', (data = new Tab(this)))
      if (typeof option == 'string') data[option]()
    })
  }

  $.fn.tab.Constructor = Tab


 /* TAB DATA-API
  * ============ */

  $(function () {
    $('body').on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
      e.preventDefault()
      $(this).tab('show')
    })
  })

}( window.jQuery );
define("bootstrap_tab", ["jquery"], function(){});

/*!
 * Hacked by huyz 2011-07-22 to add two timeouts to throttle as per
 * https://github.com/cowboy/jquery-throttle-debounce/issues/5
 * (And I broke debounce, which I don't need)
 *
 * jQuery throttle / debounce - v1.1 - 3/7/2010
 * http://benalman.com/projects/jquery-throttle-debounce-plugin/
 * 
 * Copyright (c) 2010 "Cowboy" Ben Alman
 * Dual licensed under the MIT and GPL licenses.
 * http://benalman.com/about/license/
 */

// Script: jQuery throttle / debounce: Sometimes, less is more!
//
// *Version: 1.1, Last updated: 3/7/2010*
// 
// Project Home - http://benalman.com/projects/jquery-throttle-debounce-plugin/
// GitHub       - http://github.com/cowboy/jquery-throttle-debounce/
// Source       - http://github.com/cowboy/jquery-throttle-debounce/raw/master/jquery.ba-throttle-debounce.js
// (Minified)   - http://github.com/cowboy/jquery-throttle-debounce/raw/master/jquery.ba-throttle-debounce.min.js (0.7kb)
// 
// About: License
// 
// Copyright (c) 2010 "Cowboy" Ben Alman,
// Dual licensed under the MIT and GPL licenses.
// http://benalman.com/about/license/
// 
// About: Examples
// 
// These working examples, complete with fully commented code, illustrate a few
// ways in which this plugin can be used.
// 
// Throttle - http://benalman.com/code/projects/jquery-throttle-debounce/examples/throttle/
// Debounce - http://benalman.com/code/projects/jquery-throttle-debounce/examples/debounce/
// 
// About: Support and Testing
// 
// Information about what version or versions of jQuery this plugin has been
// tested with, what browsers it has been tested in, and where the unit tests
// reside (so you can test it yourself).
// 
// jQuery Versions - none, 1.3.2, 1.4.2
// Browsers Tested - Internet Explorer 6-8, Firefox 2-3.6, Safari 3-4, Chrome 4-5, Opera 9.6-10.1.
// Unit Tests      - http://benalman.com/code/projects/jquery-throttle-debounce/unit/
// 
// About: Release History
// 
// 1.1 - (3/7/2010) Fixed a bug in <jQuery.throttle> where trailing callbacks
//       executed later than they should. Reworked a fair amount of internal
//       logic as well.
// 1.0 - (3/6/2010) Initial release as a stand-alone project. Migrated over
//       from jquery-misc repo v0.4 to jquery-throttle repo v1.0, added the
//       no_trailing throttle parameter and debounce functionality.
// 
// Topic: Note for non-jQuery users
// 
// jQuery isn't actually required for this plugin, because nothing internal
// uses any jQuery methods or properties. jQuery is just used as a namespace
// under which these methods can exist.
// 
// Since jQuery isn't actually required for this plugin, if jQuery doesn't exist
// when this plugin is loaded, the method described below will be created in
// the `Cowboy` namespace. Usage will be exactly the same, but instead of
// $.method() or jQuery.method(), you'll need to use Cowboy.method().

(function(window,undefined){
  '$:nomunge'; // Used by YUI compressor.
  
  // Since jQuery really isn't required for this plugin, use `jQuery` as the
  // namespace only if it already exists, otherwise use the `Cowboy` namespace,
  // creating it if necessary.
  var $ = window.jQuery || window.Cowboy || ( window.Cowboy = {} ),
    
    // Internal method reference.
    jq_throttle;
  
  // Method: jQuery.throttle
  // 
  // Throttle execution of a function. Especially useful for rate limiting
  // execution of handlers on events like resize and scroll. If you want to
  // rate-limit execution of a function to a single time, see the
  // <jQuery.debounce> method.
  // 
  // In this visualization, | is a throttled-function call and X is the actual
  // callback execution:
  // 
  // > Throttled with `no_trailing` specified as false or unspecified:
  // > ||||||||||||||||||||||||| (pause) |||||||||||||||||||||||||
  // > X    X    X    X    X    X        X    X    X    X    X    X
  // > 
  // > Throttled with `no_trailing` specified as true:
  // > ||||||||||||||||||||||||| (pause) |||||||||||||||||||||||||
  // > X    X    X    X    X             X    X    X    X    X
  // 
  // Usage:
  // 
  // > var throttled = jQuery.throttle( delay, [ no_trailing, ] callback );
  // > 
  // > jQuery('selector').bind( 'someevent', throttled );
  // > jQuery('selector').unbind( 'someevent', throttled );
  // 
  // This also works in jQuery 1.4+:
  // 
  // > jQuery('selector').bind( 'someevent', jQuery.throttle( delay, [ no_trailing, ] callback ) );
  // > jQuery('selector').unbind( 'someevent', callback );
  // 
  // Arguments:
  // 
  //  delay - (Number) A zero-or-greater delay in milliseconds. For event
  //    callbacks, values around 100 or 250 (or even higher) are most useful.
  //  no_trailing - (Boolean) Optional, defaults to false. If no_trailing is
  //    true, callback will only execute every `delay` milliseconds while the
  //    throttled-function is being called. If no_trailing is false or
  //    unspecified, callback will be executed one final time after the last
  //    throttled-function call. (After the throttled-function has not been
  //    called for `delay` milliseconds, the internal counter is reset)
  //  callback - (Function) A function to be executed after delay milliseconds.
  //    The `this` context and all arguments are passed through, as-is, to
  //    `callback` when the throttled-function is executed.
  // 
  // Returns:
  // 
  //  (Function) A new, throttled, function.
  
  $.throttle = jq_throttle = function( callback_interval, burst_interval, no_trailing, callback, debounce_mode ) {
    // After wrapper has stopped being called, this timeout ensures that
    // `callback` is executed at the proper times in `throttle` and `end`
    // debounce modes.
    var timeout_id,
      
      // Keep track of the last time `callback` was executed.
      last_exec = 0;
    
    // `no_trailing` defaults to falsy.
    if ( typeof no_trailing !== 'boolean' ) {
      debounce_mode = callback;
      callback = no_trailing;
      no_trailing = undefined;
    }
    
    // The `wrapper` function encapsulates all of the throttling / debouncing
    // functionality and when executed will limit the rate at which `callback`
    // is executed.
    function wrapper() {
      var that = this,
        elapsed = +new Date() - last_exec,
        args = arguments;
      
      // Execute `callback` and update the `last_exec` timestamp.
      function exec() {
        last_exec = +new Date();
        callback.apply( that, args );
      };
      
      // If `debounce_mode` is true (at_begin) this is used to clear the flag
      // to allow future `callback` executions.
      function clear() {
        timeout_id = undefined;
      };
      
      if ( debounce_mode && !timeout_id ) {
        // Since `wrapper` is being called for the first time and
        // `debounce_mode` is true (at_begin), execute `callback`.
        exec();
      }
      
      // Clear any existing timeout.
      timeout_id && clearTimeout( timeout_id );
      
      if ( debounce_mode === undefined && elapsed > callback_interval ) {
        // In throttle mode, if `delay` time has been exceeded, execute
        // `callback`.
        exec();
        
      } else if ( no_trailing !== true ) {
        // In trailing throttle mode, since `delay` time has not been
        // exceeded, schedule `callback` to execute `delay` ms after most
        // recent execution.
        // 
        // If `debounce_mode` is true (at_begin), schedule `clear` to execute
        // after `delay` ms.
        // 
        // If `debounce_mode` is false (at end), schedule `callback` to
        // execute after `delay` ms.
        timeout_id = setTimeout( debounce_mode ? clear : exec, debounce_mode === undefined ? burst_interval : delay );
      }
    };
    
    // Set the guid of `wrapper` function to the same of original callback, so
    // it can be removed in jQuery 1.4+ .unbind or .die by using the original
    // callback as a reference.
    if ( $.guid ) {
      wrapper.guid = callback.guid = callback.guid || $.guid++;
    }
    
    // Return the wrapper function.
    return wrapper;
  };
  
  // Method: jQuery.debounce
  // 
  // Debounce execution of a function. Debouncing, unlike throttling,
  // guarantees that a function is only executed a single time, either at the
  // very beginning of a series of calls, or at the very end. If you want to
  // simply rate-limit execution of a function, see the <jQuery.throttle>
  // method.
  // 
  // In this visualization, | is a debounced-function call and X is the actual
  // callback execution:
  // 
  // > Debounced with `at_begin` specified as false or unspecified:
  // > ||||||||||||||||||||||||| (pause) |||||||||||||||||||||||||
  // >                          X                                 X
  // > 
  // > Debounced with `at_begin` specified as true:
  // > ||||||||||||||||||||||||| (pause) |||||||||||||||||||||||||
  // > X                                 X
  // 
  // Usage:
  // 
  // > var debounced = jQuery.debounce( delay, [ at_begin, ] callback );
  // > 
  // > jQuery('selector').bind( 'someevent', debounced );
  // > jQuery('selector').unbind( 'someevent', debounced );
  // 
  // This also works in jQuery 1.4+:
  // 
  // > jQuery('selector').bind( 'someevent', jQuery.debounce( delay, [ at_begin, ] callback ) );
  // > jQuery('selector').unbind( 'someevent', callback );
  // 
  // Arguments:
  // 
  //  delay - (Number) A zero-or-greater delay in milliseconds. For event
  //    callbacks, values around 100 or 250 (or even higher) are most useful.
  //  at_begin - (Boolean) Optional, defaults to false. If at_begin is false or
  //    unspecified, callback will only be executed `delay` milliseconds after
  //    the last debounced-function call. If at_begin is true, callback will be
  //    executed only at the first debounced-function call. (After the
  //    throttled-function has not been called for `delay` milliseconds, the
  //    internal counter is reset)
  //  callback - (Function) A function to be executed after delay milliseconds.
  //    The `this` context and all arguments are passed through, as-is, to
  //    `callback` when the debounced-function is executed.
  // 
  // Returns:
  // 
  //  (Function) A new, debounced, function.
  
  $.debounce = function( delay, at_begin, callback ) {
    return callback === undefined
      ? jq_throttle( delay, at_begin, false )
      : jq_throttle( delay, callback, at_begin !== false );
  };
  
})(this);

define("throttle", ["jquery"], function(){});

(function(e){var t=/(^|["'(\s]|&lt;)((?:www|m)\.\S+?\.\S+?)((?:[:?,]|\.+)?(?:\s|$|&gt;|[)"']))/g,i=/(^|["'(\s]|&lt;)((?:(?:https?|ftp):\/\/|mailto:)\S+?)((?:[:?,]|\.+)?(?:\s|$|&gt;|[)"']))/g,a=function(e){return e.replace(t,'$1<a href="<``>://$2">$2</a>$3').replace(i,'$1<a href="$2">$2</a>$3').replace(/"<``>/g,'"http')},o=e.fn.linkify=function(t){e.isPlainObject(t)||(t={use:"string"==typeof t?t:void 0,handleLinks:e.isFunction(t)?t:arguments[1]});var i,n=t.use,s=o.plugins||{},r=[a],l=[],u=t.handleLinks;if(void 0==n||"*"==n)for(var c in s)r.push(s[c]);else{n=e.isArray(n)?n:e.trim(n).split(/ *, */);for(var d,c,p=0,h=n.length;h>p;p++)c=n[p],d=s[c],d&&r.push(d)}return this.each(function(){for(var t=this.childNodes,a=t.length;a--;){var o=t[a];if(3==o.nodeType){var n=o.nodeValue;if(n.length>1&&/\S/.test(n)){var s,c;i=i||e("<div/>")[0],i.innerHTML="",i.appendChild(o.cloneNode(!1));for(var d,p=i.childNodes,h=0;d=r[h];h++)for(var f,m=p.length;m--;)f=p[m],3==f.nodeType&&(n=f.nodeValue,n.length>1&&/\S/.test(n)&&(c=n,n=n.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;"),n=e.isFunction(d)?d(n):n.replace(d.re,d.tmpl),s=s||c!=n,c!=n&&e(f).after(n).remove()));n=i.innerHTML,u&&(n=e("<div/>").html(n),l=l.concat(n.find("a").toArray().reverse()),n=n.contents()),s&&e(o).after(n).remove()}}else 1!=o.nodeType||/^(a|button|textarea)$/i.test(o.tagName)||arguments.callee.call(o)}}),u&&u(e(l.reverse())),this};o.plugins={mailto:{re:/(^|["'(\s]|&lt;)([^"'(\s&]+?@.+\.[a-z]{2,7})(([:?]|\.+)?(\s|$)|&gt;|[)"',])/gi,tmpl:'$1<a href="mailto:$2">$2</a>$3'}}})(jQuery);
define("jquery.linkify", ["jquery"], function(){});

(function(c){if(window.jQuery)c(jQuery),c=jQuery.noop;"function"===typeof define&&define.amd&&define.amd.jQuery&&define("polyfiller",["jquery"],c)})(function(c){var A=c(document.scripts||"script"),o=c.event.special,B=c([]),g=window.Modernizr,r=window.asyncWebshims,z=g.addTest,w=parseFloat(c.browser.version,10),p=window.Object,D=window.html5||{};g.genericDOM=!!c("<video><div></div></video>")[0].innerHTML;g.advancedObjectProperties=g.objectAccessor=g.ES5=!!("create"in p&&"seal"in p);var d={version:"1.8.10RC2",
cfg:{useImportantStyles:!0,waitReady:!0,extendNative:!0,loadStyles:!0,disableShivMethods:!0,basePath:function(){var a=A.filter('[src*="polyfiller.js"]'),a=a[0]||a.end()[a.end().length-1],a=(c.support.hrefNormalized?a.src:a.getAttribute("src",4)).split("?")[0];return a=a.slice(0,a.lastIndexOf("/")+1)+"shims/"}()},bugs:{},browserVersion:w,modules:{},features:{},featureList:[],setOptions:function(a,b){"string"==typeof a&&void 0!==b?k[a]=!c.isPlainObject(b)?b:c.extend(!0,k[a]||{},b):"object"==typeof a&&
c.extend(!0,k,a)},addPolyfill:function(a,b){var b=b||{},e=b.f||a;if(!l[e])l[e]=[],l[e].delayReady=0,d.featureList.push(e),k[e]={};l[e].push(a);b.options=c.extend(k[e],b.options);x(a,b);b.methodNames&&c.each(b.methodNames,function(a,b){d.addMethodName(b)})},polyfill:function(){var a=function(b){var f=[],h;if(k.disableShivMethods&&g.genericDOM&&"html5Clone"in c.support)D.shivMethods=!1;var i=function(){c("html").removeClass("loading-polyfills long-loading-polyfills");c(window).unbind(".lP");clearTimeout(h)};
f.push("loading-polyfills");c(window).bind("load.lP error.lP",i);h=setTimeout(function(){c("html").addClass("long-loading-polyfills")},600);k.waitReady&&c.isReady&&d.warn("Call webshims.polyfill before DOM-Ready or set waitReady to false.");q(b,i);k.useImportantStyles&&f.push("polyfill-important");f[0]&&c("html").addClass(f.join(" "));k.loadStyles&&s.loadCSS("styles/shim.css");a=c.noop},b;return function(e){var f=[],e=e||d.featureList;"string"==typeof e&&(e=e.split(" "));b||(b=-1!==c.inArray("forms",
e),!b&&-1!==c.inArray("forms-ext",e)&&(e.push("forms"),b=!0));k.waitReady&&(c.readyWait++,q(e,function(){c.ready(!0)}));c.each(e,function(a,b){l[b]?(b!==l[b][0]&&q(l[b],function(){n(b,!0)}),f=f.concat(l[b])):(d.warn("could not find webshims-feature (aborted): "+b),n(b,!0))});a(e);u(f)}}(),reTest:function(){var a,b,e=function(e,h){var i=m[h],d=h+"Ready",g;if(i&&!i.loaded&&!(i.test&&c.isFunction(i.test)?i.test([]):i.test)){o[d]&&delete o[d];if((g=l[i.f])&&!b)g.delayReady++,q(h,function(){g.delayReady--;
n(i.f,g.callReady)});a.push(h)}};return function(d,h){b=h;"string"==typeof d&&(d=d.split(" "));a=[];c.each(d,e);u(a)}}(),isReady:function(a,b){if(l[a]&&0<l[a].delayReady){if(b)l[a].callReady=!0;return!1}a+="Ready";if(b){if(o[a]&&o[a].add)return!0;o[a]=c.extend(o[a]||{},{add:function(b){b.handler.call(this,a)}});c.event.trigger(a)}return!(!o[a]||!o[a].add)||!1},ready:function(a,b,e){"string"==typeof a&&(a=a.split(" "));e||(a=c.map(c.grep(a,function(a){return!n(a)}),function(a){return a+"Ready"}));
a.length?(e=a.shift(),c(document).one(e,function(){q(a,b,!0)})):b(c,d,window,document)},fixHTML5:function(a){return a},capturingEvents:function(a,b){document.addEventListener&&("string"==typeof a&&(a=[a]),c.each(a,function(a,f){var h=function(a){a=c.event.fix(a);b&&d.capturingEventPrevented&&d.capturingEventPrevented(a);return c.event.handle.call(this,a)};o[f]=o[f]||{};!o[f].setup&&!o[f].teardown&&c.extend(o[f],{setup:function(){this.addEventListener(f,h,!0)},teardown:function(){this.removeEventListener(f,
h,!0)}})}))},register:function(a,b){var e=m[a];if(e){if(e.noAutoCallback){var f=function(){b(c,d,window,document,void 0,e.options);n(a,!0)};e.d?q(e.d,f):f()}}else d.warn("can't find module: "+a)},c:{},loader:{addModule:function(a,b){m[a]=b;b.name=b.name||a;if(!b.c)b.c=[];c.each(b.c,function(b,c){d.c[c]||(d.c[c]=[]);d.c[c].push(a)})},loadList:function(){var a=[],b=function(b,e){"string"==typeof e&&(e=[e]);c.merge(a,e);s.loadScript(b,!1,e)},e=function(b,e){if(n(b)||-1!=c.inArray(b,a))return!0;var d=
m[b];if(d)if(d=d.test&&c.isFunction(d.test)?d.test(e):d.test)n(b,!0);else return!1;return!0},f=function(a,b){if(a.d&&a.d.length){var d=function(a,d){!e(d,b)&&-1==c.inArray(d,b)&&b.push(d)};c.each(a.d,function(a,b){m[b]?d(a,b):l[b]&&(c.each(l[b],d),q(l[b],function(){n(b,!0)}))});if(!a.noAutoCallback)a.noAutoCallback=!0}};return function(h){var i,g=[],j,k,l=function(e,h){k=h;c.each(d.c[h],function(b,d){if(-1==c.inArray(d,g)||-1!=c.inArray(d,a))return k=!1});if(k)return b("combos/"+k,d.c[k]),!1};for(j=
0;j<h.length;j++)i=m[h[j]],!i||e(i.name,h)?i||d.warn("could not find: "+h[j]):(i.css&&s.loadCSS(i.css),i.loadInit&&i.loadInit(),i.loaded=!0,f(i,h),g.push(i.name));for(j=0,h=g.length;j<h;j++)k=!1,i=g[j],-1==c.inArray(i,a)&&("noCombo"!=d.debug&&c.each(m[i].c,l),k||b(m[i].src||i,i))}}(),makePath:function(a){if(-1!=a.indexOf("//")||0===a.indexOf("/"))return a;-1==a.indexOf(".")&&(a+=".js");k.addCacheBuster&&(a+=k.addCacheBuster);return k.basePath+a},loadCSS:function(){var a,b=[];return function(d){d=
this.makePath(d);-1==c.inArray(d,b)&&(a=a||c("link, style")[0]||c("script")[0],b.push(d),c('<link rel="stylesheet" />').insertBefore(a).attr({href:d}))}}(),loadScript:function(){var a=[];return function(b,d,f){b=s.makePath(b);if(-1==c.inArray(b,a)){var h=function(){h=null;d&&d();f&&("string"==typeof f&&(f=f.split(" ")),c.each(f,function(a,b){m[b]&&(m[b].afterLoad&&m[b].afterLoad(),n(!m[b].noAutoCallback?b:b+"FileLoaded",!0))}))};a.push(b);window.require?require([b],h):window.sssl?sssl(b,h):window.yepnope?
yepnope.injectJs(b,h):window.steal&&steal(b).then(h)}}}()}};c.webshims=d;var w=("https:"==location.protocol?"https://":"http://")+"ajax.googleapis.com/ajax/libs/",C=w+"jqueryui/1.8.18/",k=d.cfg,l=d.features,n=d.isReady,q=d.ready,j=d.addPolyfill,m=d.modules,s=d.loader,u=s.loadList,x=s.addModule,v=[],E={warn:1,error:1};d.addMethodName=function(a){var a=a.split(":"),b=a[1];1==a.length&&(b=a[0]);a=a[0];c.fn[a]=function(){return this.callProp(b,arguments)}};c.fn.callProp=function(a,b){var e;b||(b=[]);
this.each(function(){var f=c.prop(this,a);if(f&&f.apply){if(e=f.apply(this,b),void 0!==e)return!1}else d.warn(a+" is not a method of "+this)});return void 0!==e?e:this};d.activeLang=function(){var a=navigator.browserLanguage||navigator.language||"";q("webshimLocalization",function(){d.activeLang(a)});return function(b){if(b)if("string"==typeof b)a=b;else if("object"==typeof b){var c=arguments,f=this;q("webshimLocalization",function(){d.activeLang.apply(f,c)})}return a}}();c.each(["log","error","warn",
"info"],function(a,b){d[b]=function(a){if((E[b]&&!1!==d.debug||d.debug)&&window.console&&console.log)return console[console[b]?b:"log"](a)}});(function(){c.isDOMReady=c.isReady;if(c.isDOMReady)n("DOM",!0);else{var a=c.ready;c.ready=function(b){if(!0!==b&&!c.isDOMReady)document.body?(c.isDOMReady=!0,n("DOM",!0),c.ready=a):setTimeout(function(){c.ready(b)},13);return a.apply(this,arguments)}}c(function(){c.isDOMReady=!0;n("DOM",!0);setTimeout(function(){n("WINDOWLOAD",!0)},9999)});c(window).load(function(){n("WINDOWLOAD",
!0)})})();(function(){var a=[];c.extend(d,{addReady:function(b){var c=function(a,c){d.ready("DOM",function(){b(a,c)})};a.push(c);c(document,B)},triggerDomUpdate:function(b){if(!b||!b.nodeType)b&&b.jquery&&b.each(function(){d.triggerDomUpdate(this)});else{var e=b.nodeType;if(!(1!=e&&9!=e)){var f=b!==document?c(b):B;c.each(a,function(a,c){c(b,f)})}}}});c.fn.htmlPolyfill=function(a){a=c.fn.html.call(this,a?d.fixHTML5(a):a);a===this&&c.isDOMReady&&this.each(function(){1==this.nodeType&&d.triggerDomUpdate(this)});
return a};c.each(["after","before","append","prepend","replaceWith"],function(a,e){c.fn[e+"Polyfill"]=function(a){a=c(d.fixHTML5(a));c.fn[e].call(this,a);c.isDOMReady&&a.each(function(){1==this.nodeType&&d.triggerDomUpdate(this)});return this}});c.each(["insertAfter","insertBefore","appendTo","prependTo","replaceAll"],function(a,e){c.fn[e.replace(/[A-Z]/,function(a){return"Polyfill"+a})]=function(){c.fn[e].apply(this,arguments);d.triggerDomUpdate(this);return this}});c.fn.updatePolyfill=function(){d.triggerDomUpdate(this);
return this};c.each(["getNativeElement","getShadowElement","getShadowFocusElement"],function(a,d){c.fn[d]=function(){return this}})})();(function(){var a=p.prototype.hasOwnProperty,b=["configurable","enumerable","writable"],e=function(a){for(var c=0;3>c;c++)if(void 0===a[b[c]]&&("writable"!==b[c]||void 0!==a.value))a[b[c]]=!0},f=function(b){if(b)for(var c in b)a.call(b,c)&&e(b[c])};if(p.create)d.objectCreate=function(a,b,d){f(b);a=p.create(a,b);if(d)a.options=c.extend(!0,{},a.options||{},d),d=a.options;
a._create&&c.isFunction(a._create)&&a._create(d);return a};p.defineProperty&&(d.defineProperty=function(a,b,c){e(c);return p.defineProperty(a,b,c)});if(p.defineProperties)d.defineProperties=function(a,b){f(b);return p.defineProperties(a,b)};d.getOwnPropertyDescriptor=p.getOwnPropertyDescriptor;d.getPrototypeOf=p.getPrototypeOf})();x("jquery-ui",{src:C+"jquery-ui.min.js",test:function(){return!(!c.widget||!c.Widget)}});x("input-widgets",{src:"",test:function(){return!this.src||!(c.widget&&(!c.fn.datepicker||
!c.fn.slider))}});x("swfobject",{src:w+"swfobject/2.2/swfobject.js",test:function(){return"swfobject"in window}});j("es5",{test:!(!g.ES5||!Function.prototype.bind),c:[10,1,22]});j("dom-extend",{f:"dom-support",noAutoCallback:!0,d:["es5"],c:[10,9,12,17,16,8,1,24,19,11,13]});"localstorage"in g&&j("json-storage",{test:g.localstorage&&"sessionStorage"in window&&"JSON"in window,loadInit:function(){u(["swfobject"])},noAutoCallback:!0,c:[14]});"geolocation"in g&&j("geolocation",{test:g.geolocation,options:{destroyWrite:!0},
d:["json-storage"],c:[14,15]});(function(){if("canvas"in g){var a;j("canvas",{src:"excanvas",test:g.canvas,options:{type:"excanvas"},noAutoCallback:!0,loadInit:function(){var b=this.options.type;if(b&&-1!==b.indexOf("flash")&&(!window.swfobject||swfobject.hasFlashPlayerVersion("9.0.0")))window.FlashCanvasOptions=window.FlashCanvasOptions||{},a=FlashCanvasOptions,"flash"==b?(c.extend(a,{swfPath:k.basePath+"FlashCanvas/"}),this.src="FlashCanvas/flashcanvas"):(c.extend(a,{swfPath:k.basePath+"FlashCanvasPro/"}),
this.src="FlashCanvasPro/flashcanvas")},afterLoad:function(){d.addReady(function(a,d){c("canvas",a).add(d.filter("canvas")).each(function(){!this.getContext&&window.G_vmlCanvasManager&&G_vmlCanvasManager.initElement(this)});a==document&&n("canvas",!0)})},methodNames:["getContext"],d:["dom-support"]})}})();var y=g.input,t=g.inputtypes;if(y&&t){z("formvalidation",function(){return!(!y.required||!y.pattern)});if(g.formvalidation)d.bugs.bustedValidity=!(c('<input type="date" value="1488-12-11" />')[0].validity||
{valid:!0}).valid;z("styleableinputrange",function(){if(!t.range)return!1;var a=document.createElement("input");a.setAttribute("type","range");return void 0!==a.style.WebkitAppearance});d.validationMessages=d.validityMessages=[];d.inputTypes={};j("form-core",{f:"forms",d:["es5"],test:function(){if(this.options.lightweightDatalist&&!this.datalistLoaded)this.datalistLoaded=!0,m["form-datalist"].f="forms",d.reTest(["form-datalist"]);return!1},options:{placeholderType:"value",langSrc:"i18n/errormessages-",
availabeLangs:"ar,ch-ZN,el,es,fr,he,hi,hu,it,ja,nl,pt-PT,ru".split(",")},methodNames:["setCustomValidity","checkValidity"],c:[3,2,59,17,16,5,4,24,19]});g.formvalidation&&!d.bugs.bustedValidity?(j("form-extend",{f:"forms",src:"form-native-extend",test:function(a){return(m["form-number-date-api"].test()||-1==c.inArray("form-number-date-api",a||[]))&&!this.options.overrideMessages},d:["form-core","dom-support","form-message"],c:[18,7,59,5]}),v=v.concat([2,3,23,21])):(v=v.concat([18,7,4,59,5]),j("form-extend",
{f:"forms",src:"form-shim-extend",test:function(){return!1},d:["form-core","dom-support"],c:[3,2,23,21]}));j("form-message",{f:"forms",test:function(a){return!(this.options.customMessages||!g.formvalidation||!m["form-extend"].test(a)||d.bugs.validationMessage)},d:["dom-support"],c:[3,2,23,21,59,17,5,4]});d.addPolyfill("form-output",{f:"forms",test:"value"in document.createElement("output"),d:["dom-support"],c:[3,2,23,21]});j("form-number-date-api",{f:"forms-ext",uiTest:function(){return t.range&&
t.date&&t.time&&t.number},test:function(){return this.uiTest()&&!d.bugs.valueAsNumberSet},d:["forms","dom-support"],c:[18,7,6]});j("form-number-date-ui",{f:"forms-ext",test:function(){return m["form-number-date-api"].test()&&!this.options.replaceUI},d:["forms","dom-support","form-number-date-api"],loadInit:function(){u(["jquery-ui"]);m["input-widgets"].src&&u(["input-widgets"])},options:{stepArrows:{number:1,time:1},calculateWidth:!0,slider:{},datepicker:{},langSrc:C+"i18n/jquery.ui.datepicker-",
recalcWidth:!0},c:[18,7,6]});j("form-datalist",{f:"forms-ext",test:y.list,d:["form-core","dom-support"],c:[3,59,18,24,19,11]})}"details"in g||z("details",function(){return"open"in document.createElement("details")});j("details",{test:g.details,d:["dom-support"],options:{text:"Details"},c:[12,13,15]});if("audio"in g&&"video"in g)d.mediaelement={},j("mediaelement-core",{f:"mediaelement",noAutoCallback:!0,d:["swfobject","dom-support"],c:[10,9,12,17,16,8,22,23,24,20]}),j("mediaelement-swf",{f:"mediaelement",
options:{hasToPlay:"any",preferFlash:!1,jwVars:{},jwParams:{},jwAttrs:{},changeJW:c.noop},methodNames:["play","pause","canPlayType","mediaLoad:load"],d:["swfobject","dom-support"],test:function(){if(!g.audio||!g.video)return!1;var a=this.options,b=a.hasToPlay;return!((!window.swfobject||window.swfobject.hasFlashPlayerVersion("9.0.115"))&&(a.preferFlash||"any"!=b&&!g.video[b]&&!g.audio[b]))},c:[10,9,22,20]});j("feature-dummy",{test:!0,loaded:!0,c:v});A.filter("[data-polyfill-cfg]").each(function(){try{d.setOptions(c(this).data("polyfillCfg"))}catch(a){d.warn("error parsing polyfill cfg: "+
a)}}).end().filter("[data-polyfill]").each(function(){d.polyfill(c.trim(c(this).data("polyfill")||""))});r&&(r.cfg&&d.setOptions(r.cfg),r.lang&&d.activeLang(r.lang),"polyfill"in r&&d.polyfill(r.polyfill))});

define("webshims", ["jquery"], function(){});

(function(b){var e=function(c,a){var b=c.data("mousepresstimer");b&&clearTimeout(b);a&&c.unbind("mouseup.mousepressext mouseleave.mousepressext")};b.event.special.mousepress={setup:function(){b(this).bind("mousedown.mousepressext",function(c){var a=b(this),g=function(f){var d=0;e(a);a.data("mousepresstimer",setInterval(function(){b.event.special.mousepress.handler(a[0],c);d++;3<d&&45<f&&g(f-40)},f))},d=b(c.target).trigger("mousepressstart",[c]);e(a);a.data("mousepresstimer",setTimeout(function(){g(180)},
200));a.bind("mouseup.mousepressext mouseleave.mousepressext",function(b){e(a,!0);d.trigger("mousepressend",[b]);d=a=null})})},teardown:function(){e(b(this).unbind(".mousepressext"),!0)},handler:function(c,a){return b.event.handle.call(c,{type:"mousepress",target:a.target,pageX:a.pageX,pageY:a.pageY})}}})(jQuery);

define("webshims_mousepress", ["jquery","webshims"], function(){});

define('routers/RoutingRules',["app/Assess"],function(e){var t={submissionPreviewUrl:function(t,n,i){var a=window.location.href;return a=a.substring(0,a.indexOf("/",a.indexOf("//")+2)),a+e.Routing.redirectPath({courseId:t,assessmentId:n,submissionId:i})}};return t});
define('templates/SubmissionBaseView.hbs',[],function(){return function(e,t,n,i,a){function o(e){var t,i,a="";return a+='\n<div class="returnLink"><a href="',i=n.returnUrl,i?t=i.call(e,{hash:{}}):(t=e.returnUrl,t=typeof t===g?t():t),a+=v(t)+'" class="hg-internal"><i class="icon-arrow-left"></i>&nbsp;Return to list</a></div>'}function r(e,t){var i,a="";return a+='\n  <div id="topContentToolbar" class="contentToolbar form-actions">\n    <div class="contentToolbarButtons pull-right">',i=e.skippable,i=n["if"].call(e,i,{hash:{},inverse:b.noop,fn:b.program(4,s,t)}),(i||0===i)&&(a+=i),a+="\n      ",i=e.resubmit,i=n["if"].call(e,i,{hash:{},inverse:b.program(8,u,t),fn:b.program(6,l,t)}),(i||0===i)&&(a+=i),a+="\n    </div>\n  </div>"}function s(){return'<a id="assessmentSkip" role="button" href="#" class="btn hg-internal">Skip</a>'}function l(){return'<a id="assessmentSubmit" role="button" href="#" class="btn btn-primary hg-internal">Re-submit</a>'}function u(){return'<a id="assessmentSave" role="button" href="#" class="btn hg-internal">Save draft</a><a id="assessmentSubmit" role="button" href="#" class="btn btn-primary hg-internal">Submit</a>'}function c(e,t){var i,a="";return a+='\n  <div id="bottomContentToolbar" class="contentToolbar form-actions">\n    <div class="contentToolbarButtons pull-right">',i=e.skippable,i=n["if"].call(e,i,{hash:{},inverse:b.noop,fn:b.program(11,d,t)}),(i||0===i)&&(a+=i),a+="\n      ",i=e.resubmit,i=n["if"].call(e,i,{hash:{},inverse:b.program(15,h,t),fn:b.program(13,p,t)}),(i||0===i)&&(a+=i),a+="\n    </div>\n  </div>"}function d(){return'<a id="assessmentSkip" role="button" href="#" class="btn hg-internal">Skip</a>'}function p(){return'<a id="assessmentSubmit" role="button" href="#" class="btn btn-primary hg-internal">Re-submit</a>'}function h(){return'<a id="assessmentSave" role="button" href="#" class="btn hg-internal">Save draft</a><a id="assessmentSubmit" role="button" href="#" class="btn btn-primary hg-internal">Submit</a>'}n=n||e.helpers;var f,m="",g="function",v=this.escapeExpression,b=this;return f=t.returnUrl,f=n["if"].call(t,f,{hash:{},inverse:b.noop,fn:b.program(1,o,a)}),(f||0===f)&&(m+=f),m+="\n<!-- h1.assessmentTitle ",f=t.assessment,f=null==f||f===!1?f:f.title,f=typeof f===g?f():f,m+=v(f)+'-->\n<div id="assessmentForm">',f=t.editable,f=n["if"].call(t,f,{hash:{},inverse:b.noop,fn:b.program(3,r,a)}),(f||0===f)&&(m+=f),m+='\n  <div id="assessmentFormContent"></div>',f=t.editable,f=n["if"].call(t,f,{hash:{},inverse:b.noop,fn:b.program(10,c,a)}),(f||0===f)&&(m+=f),m+='\n</div>\n<div id="coursera-signature-modal"></div>'}});
define('views/SubmissionBaseView',["app/Assess","lib/Util","jquery","divgrow","underscore","backbone","marionette","bootstrap_tab","throttle","jquery.linkify","modelbinding","json2","webshims","webshims_mousepress","routers/RoutingRules","models/Submission","views/AssessmentNavigationView","views/BaseView","handlebars","templates/SubmissionBaseView.hbs"],function(e,t,n,i,a,o,r,s,l,u,c,d,p,h,f,m,g,v,b,y){var w=["staff","peer","self"],x={staff:"the staff",peer:"your peers",self:"yourself"},k={txt:"text/plain",csv:"text/csv",html:"text/html",htm:"text/html",css:"text/css",jpeg:"image/jpeg",jpg:"image/jpeg",gif:"image/gif",png:"image/png",pdf:"application/pdf"},_=a.values(k),C=1,A=v.extend({template:function(){return b.template(y)},events:{"click a:not(.hg-internal):not([class*='mce'])":"anchorClick"},maxWordsGraceMultiple:1.1,featuresNeeded:{},itemIdToType:{},tinyMCEHeights:[],anchorClick:function(t){var i=n(t.currentTarget).attr("href");return e.log(i),i?(t.preventDefault(),window.open(i),!1):!0},hideAllFieldErrors:function(){n(".validationErrorMessage").hide(),n(".validationError").removeClass("validationError")},displayFieldErrors:function(t){this.hideAllFieldErrors();for(var i=0;t.length>i;i++){var a,o=t[i].errorData;switch(o.reason){case"blank":a="Field cannot be blank";break;case"tooHigh":a="Field value is too high";break;case"tooLow":a="Field value is too low";break;case"notAListOption":a="Field value is not one of the valid options in the list";break;case"wordLimitExceeded":a="Word limit exceeded";break;case"invalidNumberType":a="Invalid number type";break;default:a="Error",e.error("Unknown error reason "+o.reason)}n("#"+o.id+"-validationErrorMessage").html(a).show(),n("#"+o.id+"-validationErrorContainer").children(".submissionFormField").addClass("validationError")}},renderVariant:function(i){i||(i={});var r=this,s=r.model.get("overallEvaluationModel"),l=s!==void 0;this.featuresNeeded.richTextEditor=!1,this.featuresNeeded.webshims=!1,i.submissionDisabledAttribute=i.editableSubmission?"":'disabled="disabled" ',i.evaluationDisabledAttribute=i.editableEvaluation?"":'disabled="disabled" ',i.submissionMceEditorClass=i.editableSubmission?"mceEditor":"",i.evaluationMceEditorClass=i.editableEvaluation?"mceEditor":"",i.shrinkableClass=i.shrinkLargeInstructions?" shrinkableBlock":"",this.model.set("editable",i.editableSubmission||i.editableEvaluation),(i.editableSubmission&&this.model.get("submissionModel").get("submitTime")||i.editableEvaluation&&this.model.get("evaluationModel").get("submitTime"))&&this.model.set("resubmit",!0),i.skippableEvaluation&&!this.model.get("evaluationModel").get("submitTime")&&this.model.set("skippable",!0);var u=[],d=function(){return u.length>0?' aria-labelledby="'+u[u.length-1]+'"':""},p=function(e,t,n){return e.parameters&&a.has(e.parameters,t)?e.parameters[t]:n},h=function(n,o,c){if(!n||!a.isArray(n)||!n.length)return"";var f="",m="",g="",v="",b="",y={},k=function(){f+=g,g=""},_=function(){f+=v,v=""},A=function(){f+=b,b=""},S=function(){k(),_(),g||(f+='<div class="assessmentExposition">',g="</div>")},T=function(){k(),v||(f+='<div class="assessmentAnswer"'+d()+">",v="</div>")},j=function(){k(),_(),b||(f+='<div class="assessmentEvaluation"'+d()+">",b="</div>")},E=function(e){return"training"===i.step?'<div id="trainingFeedback-'+e.id+'" class="trainingFeedback"'+' style="display:none;"'+"></div>":""},I=function(e){var t;return t=a.isObject(e)&&!a.isArray(e)&&e.children?e.children:e,a.isArray(t)&&a.all(t,function(e){return e.hiddenForPhases&&a.include(e.hiddenForPhases,i.step)})?!0:e.hiddenForPhases&&a.include(e.hiddenForPhases,i.step)?!0:!1},N=function(e){return'<div id="'+e.id+'-validationErrorMessage" class="validationErrorMessage"></div>'},M=function(e){return'<div id="'+e.id+'-validationErrorContainer">'};return a.each(n,function(n){var g,v,b="submission.fields."+n.id,_="evaluation.fields."+n.id,A="fields."+n.id;r.itemIdToType[n.id]=n.type;var D=o&&o.inTrainingFeedback||n.partOfTrainingFeedback;if((D||e.adminMode||!n.restrictedTo||!a.find(n.restrictedTo,function(e){return"staff"===e}))&&!I(n)){switch(n.type){case"richText":S(),f+='<div class="assessmentText'+(o.inEvaluation?"":i.shrinkableClass)+'">'+n.html+"</div>";break;case"textField":T(),f+=i.editableSubmission?'<input type="text" id="textfield-'+n.id+'" '+i.submissionDisabledAttribute+'data-modelbind="'+b+'"'+d()+' style="width: 100%" />':'<div class="assessmentText" data-bind="text '+b+'"></div>';break;case"richTextArea":T(),i.editableSubmission?(g=parseInt(p(n,"cssHeight","400px"),10),r.tinyMCEHeights.push(g),v=i.submissionMceEditorClass?i.submissionMceEditorClass+r.tinyMCEHeights.length:"",v&&(v+=" mceEditor"),f+=N(n),f+=M(n),f+='<textarea id="textarea-'+n.id+'" '+i.submissionDisabledAttribute+'data-modelbind="'+b+'"'+d()+' data-max-words="'+p(n,"maxWords","0")+'"'+' class="submissionFormField '+v+'" style="width: 100%;" />',f+="</div>",r.featuresNeeded.richTextEditor=!0,p(n,"enableUpload",!0)&&(f+=r.makeUploadButton(n.id,r.model.get("assessmentModel")))):f+='<div class="assessmentText" data-bind="html '+b+'"></div>';break;case"gradingNumber":if(j(),"results"===i.step&&l)a(w).each(function(e){var n=t.round(s.get(A+"."+e),C);n!==c&&(f+="<p>Score from "+x[e]+": <b>"+n+"</b></p>")});else{var P,R,O="Score";if(n.parameters.min!==c&&n.parameters.max!==c&&(O+=" from "+n.parameters.min+" to "+n.parameters.max),f+=N(n),f+=M(n),"list"===n.parameters.numberType){for(f+='<select id="evaluationField-'+n.id+'" '+i.evaluationDisabledAttribute+'data-modelbind="'+_+'"'+d()+' class="submissionFormField">',f+='  <option value=""></option>',e.assert(n.parameters.options&&n.parameters.options.length>=1,"No options parameter found the spec of a list numberType"),P=0,R=n.parameters.options.length;R>P;P++){var L=n.parameters.options[P];f+='  <option value="'+L.id+'">'+L.value+(L.label?": "+L.label:"")+"</option>"}f+="</select>"}else if("integer"===n.parameters.numberType&&10>=n.parameters.max-n.parameters.min){for(f+='<select id="evaluationField-'+n.id+'" '+i.evaluationDisabledAttribute+'data-modelbind="'+_+'"'+d()+' class="submissionFormField">',f+='  <option value=""></option>',P=n.parameters.min;n.parameters.max>=P;P++)f+='  <option value="'+P+'">'+P+"</option>";f+="</select>"}else f+='<input id="evaluationField-'+n.id+'" '+'type="text" '+i.evaluationDisabledAttribute+'data-modelbind="'+_+'" min="'+n.parameters.min+'" max="'+n.parameters.max+'"'+d()+' placeholder="'+O+'" />';f+="</div>",f+=E(n),r.featuresNeeded.webshims=!0}break;case"gradingRadio":j(),f+=N(n),f+=M(n),f+='<div class="gradingRadio">';var B=0;a.each(n.parameters.options,function(e){var t="evaluationField-"+n.id+"-"+B;B++,f+='<label for="'+t+'"><input id="'+t+'" type="radio" '+i.evaluationDisabledAttribute+' name="'+_+'" value="'+e.value+'" />'+e.labelHtml+"</label><br />"}),f+="</div>",f+="</div>",f+=E(n);break;case"gradingTextArea":case"gradingRichTextArea":if(j(),D&&"training"===i.step)f+=E(n);else if(D&&"calibration"!==i.step);else if("results"===i.step&&l){var H=s.get(A);if("gradingRichTextArea"===n.type){f+='<div class="tabbable">';var $='<div class="tab-content">',z='<ul class="nav nav-tabs">',q=1;a.each(H,function(e,t){var i=n.id+"-"+q;z+='<li style="float: left;"'+(1===q?' class="active">':">")+'<a href="#tab'+i+'" data-toggle="tab">'+t+"</a></li>",$+='<div id="tab'+i+'" class="tab-pane'+(1===q?' active">':'">')+"<p>"+e+"</p></div>",q++}),$+="</div>",z+="</ul>",f+=z,f+=$,f+="</div>"}else a.each(H,function(e,t){t=t.replace(/^student/,"peer "),f+='<div class="overallEvaluationFeedbackSection"><span class="overallEvaluationFeedbackAuthor">'+t+" &rarr;</span> "+e+"</div>"})}else{var F=i.evaluationDisabledAttribute;g=200,r.tinyMCEHeights.push(g),v=i.evaluationMceEditorClass?i.evaluationMceEditorClass+r.tinyMCEHeights.length:"",v&&(v+=" mceEditor"),F||D||"training"!==i.step||(r.tinyMCEHeights.pop(),F='disabled="disabled" ',v=""),f+=N(n),f+=M(n),"gradingTextArea"===n.type?f+='<textarea data-modelbind="'+_+'" '+F+d()+' rows="2" style="width: 100%; resize: vertical" class="submissionFormField"></textarea>':"gradingRichTextArea"===n.type&&(f+='<textarea id="textarea-'+n.id+'" '+F+'data-modelbind="'+_+'"'+d()+' class="'+v+'" style="width: 100%; height: '+g+'px"></textarea>',i.editableEvaluation&&(r.featuresNeeded.richTextEditor=!0)),f+="</div>"}break;case"group2":case"group":if(n.children){var U=!1;k(),f+='<div id="evaluatedGroup-'+n.id+'" class="'+("group"===n.type?"assessmentGroup":"assessmentSection")+(D&&"training"===i.step?' trainingFeedback" style="display:none':"")+'">',D&&"training"!==i.step&&"calibration"!==i.step||"group"===n.type&&n.html&&(S(),f+='<div id="assessmentText-'+n.id+'" class="assessmentText">'+n.html+"</div>",u.push("assessmentText-"+n.id),U=!0,k());var W=D&&a.extend({inTrainingFeedback:!0},o);f+=h(n.children,W||o),U&&(u.pop(),U=!1),m+="</div>"}else n.evaluation||e.logEvent("assessment.fields.warning",{description:"When parsing assessment form, found a malformed "+n.type+": no children or evaluation key."});break;case c:case null:case"":e.logEvent("assessment.fields.warning",{description:"Unrecognized assessment item type: "+n.type});break;default:e.logEvent("assessment.fields.warning",{description:'When parsing assessment form, unrecognized item type: "'+n.type+'"'})}if(f+=m,m="",n.evaluation){var V=a.isArray(n.evaluation);V||a(n.evaluation.sets).each(function(e){y[e.id]=e}),a.size(V?n.evaluation:n.evaluation.children)>0&&!i.hideEvaluation&&!I(n.evaluation)&&(f+='<div class="'+("group2"===n.type?"sectionEvaluationGroup":"evaluationGroup")+'" data-evaluated="'+"evaluatedGroup-"+n.id+'">',"results"===i.step&&l&&!V&&a(n.evaluation.displaySubtotals).each(function(e){var n=y[e.setId];switch(n.type){case"constraint.max":case"sum":f+='<div class="evaluationSetValueContainer"><div class="evaluationSetValueBorder"><p><b>Score subtotal</b>',"constraint.max"===n.type&&(f+=" (after limit of "+n.parameters.max+" was applied)"),f+='</p><table class="evaluationSetValueTable">',a(w).each(function(e){var i=t.round(s.get("fields."+n.id+"."+e),C);i!==c&&(f+="<tr><td>From "+x[e]+': </td> <td><input id="evaluationSetValue-'+n.id+'" class="evaluationSetValueBox"'+' value="'+i+'" disabled="disabled" /></td></tr>')}),f+="</table></div></div>"}}),f+='<div class="evaluationGroupHeader"><h3>'+("group2"===n.type?"Overall evaluation/feedback":"Evaluation/feedback on the above work")+"</h3>",i.editableEvaluation||(f+="<b>Note</b>: this section can only be filled out during the evaluation phase."),f+="</div>",f+=h(V?n.evaluation:n.evaluation.children,a.extend({inEvaluation:!0},o)),f+="</div>")}}}),k(),_(),A(),f},f=this.getTemplateSelector(),m=this.serializeData();this.beforeRender&&this.beforeRender(),this.trigger("item:before:render",r);var g=i.header!==void 0?i.header:"";g+=o.Marionette.Renderer.render(f,m),r.$el.html(g);var v=this.model.get("assessmentModel");g='<div class="'+(i.editableSubmission?"submissionForm":"evaluationForm")+'">',g+='<div id="assessmentHead">',i.title!==void 0?g+='<h1 class="assessmentTitle">'+i.title+"</h1>":i.submissionAuthor!==void 0&&(g+='<h1 class="assessmentTitle">Submission from: <span class="assessmentSubmissionAuthor">'+i.submissionAuthor+"</span></h1>"),i.isReview||i.editableSubmission||this.model.get("submissionModel").get("submitTime")||(g+='<div class="alert alert-box">No work was submitted before the submission deadline. You will not be able to evaluate the work of your peers or receive an evaluation.</div>'),g+='<div id="forumThreadLinkSection"></div>',g+="</div>","results"===i.step&&(g+=r.overallEvaluationHeaderHtml(s));var b=v.get("form");g+=h(b,{})+" </div>",v.allowsExclusionFromCirculation()&&(i.editableSubmission?(g+='<div class="alert">',g+='<p><b>Privacy choice:</b> (read <a href="../../wiki/view?page=PrivacyPolicy">privacy policy</a>)</p>',g+='<input type="checkbox" name="privacyAllowCirculation"'+(this.model.get("submissionModel").get("excludedFromCirculation")?"":'checked="checked"')+" />",g+=" I'd love to help out the course with my work.  The staff may share my submission with my classmates and other people who are curious, for things like peer assessment training, lecture slides, and publications.<br />",g+="</div>"):this.model.get("submissionModel").get("excludedFromCirculation")&&(g+='<div class="alert">',g+="The privacy setting on this submission is set to: not available for sharing.",g+="</div>")),window.AssessmentGlobals={step:i.step},r.$("#assessmentFormContent").html(g),r.insertTrainingFeedback(r.$el),("submitting"===i.step||"selfGrading"===i.step||"results"===i.step&&"sharing"!==i.realStep)&&"results"===v.access.getBestStep()&&v.isSharingEnabled()&&r.insertSharableUrl(r.$el),r.insertForumThread(r.$el),r.on("render",function(){r.$(".sectionEvaluationGroup, .evaluationGroup").each(function(e,t){var i=n(t);i.hover(function(){r.$("#"+i.attr("data-evaluated")).addClass("highlightEvaluated")},function(){r.$("#"+i.attr("data-evaluated")).removeClass("highlightEvaluated")})})}),c.Configuration.configureBindingAttributes({textarea:"data-modelbind",text:"data-modelbind",number:"data-modelbind",select:"data-modelbind",checkbox:"data-modelbind"}),c.bind(r),r.$("a[href$='.pdf'][href^='https://coursera-uploads'], a[href$='.pdf'][href^='http://coursera-uploads']").each(function(){n(this).attr("download",n(this).text())}),r.onRender&&r.onRender(),r.trigger("item:rendered",r),r.trigger("render",r)},overallEvaluationHeaderHtml:function(e){if(e===void 0)return'<div class="alert alert-block">The evaluations for this submission are not available.</div>';var n="";n+='<div class="overallGradeSection">';var i=this.model.get("assessmentModel");if(!i.isDisplayGradeEnabled())return n+="<p>See below for feedback on your work.</p></div>";var o=e.get("gradeAdjustments"),r=null;o&&!a.isEmpty(o)&&(r=t.round(e.get("adjustedGrade"),C),r===void 0&&(r=null));var s=e.get("grade");null!==r&&(n+='<p>Your effective grade is <span class="overallGradeNumber">'+r+"</span><br />",a.each(e.get("gradeAdjustments"),function(e,t){switch(t){case"incompletePeerGrading":n+="A "+e.replace(/^-/,"")+" penalty has been applied because you did not complete the entire evaluation portion of the assessment.<br />";break;case"":n+="";break;default:n+=""}}),n+="</p>"),n+=(null!==r?'<p>Your unadjusted grade is <span class="':'<p>Your grade is <span class="overallGradeNumber')+'">'+(null!==s?t.round(s,C):"<i>undetermined</i>")+"</span>";var l=e.get("gradeSources"),u=l.length;n+=0===u?".</p><p>Apparently, no one has graded your work.  If that does not sound right, please contact the staff":1===u?", which is simply":", which was calculated based on a combination of";var c="";return a.each(e.get("gradeSources"),function(e,t){switch(u>1&&t+1===u&&(n+=" and"),e){case"staff":n+=" the grade you received from the instructor or staff";break;case"peer":n+=" the grade you received from your peers";break;case"self":n+=" the grade you gave yourself"}u>2&&u>t+1&&(n+=",")}),n+=".</p>",n+=c,n+="<p>See below for details.</p></div>"},onShow:function(){var e=this;require(["tinymce"],function(t){if(e.tinyMCE=t,e.$(".shrinkableBlock").divgrow({initialHeight:150,moreText:'<i class="icon-resize-full"></i> Show more assignment details',lessText:null,showBrackets:!1}),e.$el.hide().fadeIn(),e.featuresNeeded.richTextEditor){var i;for(i=1;e.tinyMCEHeights.length>=i;i++)e.setupTinyMCE(t,"mceEditor"+i,e.tinyMCEHeights[i-1])}e.featuresNeeded.webshims&&e.setupWebshims(),window.onbeforeunload=function(){var e=!1;n('input[type="file"]').each(function(){"none"==n(this).css("display")&&(n(this).siblings("span.f_loading").css("display","none"),n(this).siblings("span.f_loader").css("display","none"),n(this).css("display",n(this).data("prevDisplayStyle")),n(this).val(""),e=!0)});var i=!1;return a.each(t.editors,function(e){e.isDirty()&&(i=!0)}),e&&i?"Warning: Since you tried to navigate away from the page, your upload was canceled. You also have unsaved changes.":e?"Warning: Since you tried to navigate away from the page, your upload was canceled.":i?"Warning: Your assignment has not been saved.":void 0}}),window.loadOrRefreshMathJax&&n(".assessmentText").each(function(){window.loadOrRefreshMathJax(this)}),n(".assessmentText").linkify()},wordCount:function(e){var t=n("<div/>").html(e.getContent().replace(/<.+?>/g,"").replace("&nbsp;"," ")).text().match(/\b/g),i=0;return t&&(i=t.length/2),i},updateWordCount:function(e,t){var i=this.wordCount(t),a=parseInt(n(t.getElement()).attr("data-max-words"),10),o="",r="black";0!==a&&i>this.maxWordsGraceMultiple*a&&(r="red",o=" (Your text is over the word limit. You will not be able to save or submit your work.)"),n("#"+t.id+"_path_row").css("color",r),e.DOM.setHTML(e.DOM.get(t.id+"_path_row"),"Words: "+i+(a?" / "+a+o:""))},setupTinyMCE:function(t,i){var o=this;t.init({init_instance_callback:function(e){a([0,1e3,3e3,6e3]).each(function(t){a.delay(function(){e.execCommand("mceAutoResize")},t)})},mode:"specific_textareas",editor_selector:i,plugins:"style,inlinepopups,contextmenu,paste,fullscreen,noneditable,tabfocus,autoresize",paste_remove_styles:!0,paste_block_drop:!0,paste_preprocess:function(e,t){/<img.*[^>]*\ssrc\s*=\s*"data:/i.test(t.content)?t.content="<div/>":(t.content=t.content.replace(/ {2}/g,"  "),t.content=t.content.replace(/\x09/g,"        "))},content_css:"/static/css/bootstrap.css,/static/css/hg.css?1",theme:"advanced",theme_advanced_buttons1:"bold,italic,formatselect,|,numlist,bullist,|,undo,redo",theme_advanced_buttons2:"",theme_advanced_buttons3:"",theme_advanced_toolbar_location:"top",theme_advanced_toolbar_align:"left",theme_advanced_statusbar_location:"bottom",theme_advanced_resizing:!0,theme_advanced_blockformats:"h2,code,blockquote",formats:{code:{block:"pre",classes:"hg-tinymce-code",remove:"all"}},width:"100%",theme_advanced_resize_horizontal:!1,theme_advanced_resizing_use_cookie:!1,autoresize_min_height:"50px",autoresize_max_height:"600px",theme_advanced_path:!1,setup:function(i){var r=n.throttle(500,50,o.updateWordCount.bind(o));i.onKeyUp.add(function(e){r(t,e)}),i.onPaste.add(function(){}),i.onLoadContent.add(function(e){o.updateWordCount(t,e)}),i.onActivate.add(function(t){var n="user.richTextarea.focus",i={};i.id=t.id,e.logEvent(n,i)}),i.onInit.add(function(e){e.plugins.contextmenu.onContextMenu.add(function(e,t){var n=navigator.platform.indexOf("Mac")>=0,i={};for(var a in t.items){var o=t.items[a];if(/^mce_/.test(a)&&o.settings){if("mceImage"===o.settings.cmd||"mceAdvImage"===o.settings.cmd||"mceLink"===o.settings.cmd||"UnLink"===o.settings.cmd)continue;n&&(o.settings.title=o.settings.title.replace(/Ctrl\+/g,"⌘"))}i[a]=o}t.items=i})}),i.onPostRender.add(function(t){n(t.getContainer()).removeAttr("aria-labelledby"),n(t.getContentAreaContainer()).children("iframe").attr("aria-labelledby",n(t.getElement()).attr("aria-labelledby")),n("#assessmentFormContent").find("td.mceToolbar > a").attr("tabIndex","-1");var i=t.id.replace(/^textarea-(.*)/,"mediaUpload-$1"),o=n("#"+i+"-form");n('input[type="file"]',o).on("change",function(){var t=n(this),i=(t.val()||"").trim();n("span.f_filebak",o).text("");var a=(i.split(".").pop()||"").toLowerCase();if(a in k){n("span.f_loading",o).css("display","inline-block"),n("span.f_loader",o).css("display","inline-block"),n("span.f_filebak",o).text(i),n(this).data("prevDisplayStyle",n(this).css("display")),n(this).css("display","none");var r="upload.start",s={};s.fileName=i,e.logEvent(r,s),o.submit()}else alert("Invalid File-Type Error:\nOnly text, image, and PDF files are allowed."),t.val("")}),n("#"+i+"-frame").on("load",function(){var o=n("#"+i+"-form"),r=n('input[name="file"]',o);n("span.f_loading",o).css("display","none"),n("span.f_loader",o).css("display","none"),r.css("display",r.data("prevDisplayStyle")),r.val("");var s,l="",u="",c="",p="",h=n(this).contents();if(h=h&&h.length>0?h[0]:null,h&&(l=(h.URL||"").trim(),h=h.documentElement),0!==l.length&&0===l.indexOf(Global.API_BASE_URL)){if(l.match(/\/uploadfile$/)){if(h&&(p="Server Error:\n\n",c=n(h).text()||"",0===c.length&&(c="Failed to upload file."),p+=c,c.trim().match(/^\{.*\}$/)))try{s=d.parse(c),s.Error?p=["Error: ",s.Error.Code,"\n\n",s.Error.Message].join(""):s.UploadResponse&&(u=s.UploadResponse.path||"",p="")}catch(f){}}else p="Network Error:\n\nFailed to upload file.";var m="",g={};if(p.length>0||0===u.length)return m="upload.error",e.logEvent(m,g),p.length>0&&alert(p),void 0;var v,b,y=(n("span.f_filebak",o).text()||"").replace(/^.*[\\\/]/,""),w=(u.split(".").pop()||"").toLowerCase();w&&0===k[w].indexOf("image/")?b=['<br /><img src="',u,'" /><br />'].join(""):(v=y,b=['<br /><a href="',u,'">',v,"</a><br />"].join("")),m="upload.success",g.fileName=y,e.logEvent(m,g),t.execCommand("mceInsertRawHTML",!1,b),a([300,1e3,3e3,6e3]).each(function(e){a.delay(function(){t.execCommand("mceAutoResize")},e)}),t.focus()}})})},template_replace_values:{username:"Some User",staffid:"991234"}}),this.on("item:before:close",function(){var e=a.clone(t.editors);a.each(e,function(e){e.remove(),e.destroy()})})},setupWebshims:function(){window.html5||(window.html5={}),window.html5.shivMethods=!1,n.webshims.setOptions("forms",{placeholderType:"over"}),n.webshims.setOptions({waitReady:!1}),n.webshims.polyfill("forms-ext")},syncRichTextEditors:function(){this.tinyMCE&&a(this.tinyMCE.editors).each(function(e){e.isDirty()&&(e.save(),n(e.getElement()).trigger("change"),e.isNotDirty=1)})},blurAllInputs:function(){n("input").blur()},insertTrainingFeedback:function(e){e=e||n("body");var t=this,i=t.model.get("trainingModel"),o=i&&i.get("feedback");o&&a(o).each(function(n,i){var a=t.itemIdToType[i];if("gradingNumber"===a)switch(n){case"low":n='<i class="icon-remove" style="color:red"></i> This score is too low.';break;case"high":n='<i class="icon-remove" style="color:red"></i> This score is too high.';break;case"ok":n='<i class="icon-ok" style="color:lime"></i> This score is just right.'}e.find("#trainingFeedback-"+i).html(n).parents(".trainingFeedback").andSelf().show()})},insertForumThread:function(e){var t=this,n=t.model.get("submissionModel"),i=t.model.get("evaluationModel"),a=function(){var t="",a=n.get("forumThreadUrl");!a||i&&!i.get("submitTime")||(t='<div class="alert alert-info">See how your classmates evaluated this submission &mdash; and continue the discussion &mdash; in <a href="'+a+'" target=_blank>this forum thread</a>.'+"</div>"),e.find("#forumThreadLinkSection").html(t)};a(),i&&i.on("change:submitTime",a),n.on("change:forumThreadUrl",a)},insertSharableUrl:function(e){var t,i=f.submissionPreviewUrl(this.model.get("assessmentModel").course.get("id"),this.model.get("assessmentModel").get("id"),this.model.get("submissionModel").get("id"));this.model.get("submissionModel").get("excludedFromCirculation")?t="You marked your submission as private, so you cannot share your submission with other people.":(t="You can share your submission with your classmates with this link: ",t+='<input id="mySubmissionShareURL" type="text" size="10" value="'+i+'" />'),e.find("#assessmentHead").append('<div class="alert alert-info">'+t+"</div>"),e.find("#mySubmissionShareURL").click(function(){n(this).select()})},makeUploadButton:function(t,i){function a(e,t){return"mediaUpload-"+e+(t?"-"+t:"")}var o=i.course.get("id"),r=i.get("id"),s="",l=[e.API_BASE_URL,"assessments/",o,"/",r,"/uploadfile"].join(""),u=(a(t,"fupload"),a(t,"form")),c=a(t,"frame"),d=e.Ajax.getCsrfToken(n);return s+=['<div class="richTextAreaUpload"><form class="hg-upload" id="',u,'" name="',u,'" autocomplete="off" action="',l,'" method="POST" enctype="multipart/form-data" class="form-horizontal" target="',c,'">'].join(""),s+=['<input value="',d,'" name="__csrf-token" type="hidden" />'].join(""),s+=['<span class="lbl">Upload file : </span><input value="Upload file" name="file" type="file" accept="',_.join(","),'" />'].join(""),s+=['<span class="f_loader"></span><span class="f_loading">Uploading...</span>'].join(""),s+=['<span class="f_filebak"></span></br>'].join(""),s+=['<iframe id="',c,'" name="',c,'" src="" style="display:none;"></iframe>'].join(""),s+="</form>",s+="</div>"}});return A});
define('views/SubmissionEditView',["app/Assess","lib/Util","jquery","underscore","json2","backbone","marionette","modelbinding","SignatureAuthModal","models/Submission","views/SubmissionBaseView","views/ViewHelpers","routers/RoutingRules"],function(e,t,n,i,a,o,r,s,l,u,c,d,p){var h=c.extend({events:function(){return i.extend({},c.prototype.events,{"click #assessmentSave":"save","click #assessmentSubmit":"submit"})},render:function(){this.renderVariant({step:"submitting",editableSubmission:this.model.get("assessmentModel").access.isStepWritable("submitting")})},numInvalidWordCounts:function(){var e=this,t=0;if(e.tinyMCE&&e.tinyMCE.editors){var i;for(i=0;e.tinyMCE.editors.length>i;i++){var a=e.wordCount(e.tinyMCE.editors[i]),o=parseInt(n(e.tinyMCE.editors[i].getElement()).attr("data-max-words"),10);if(0!==o){var r=n("#"+e.tinyMCE.editors[i].id).parent();a>e.maxWordsGraceMultiple*o?(t++,r.addClass("validationError")):r.removeClass("validationError")}}}return t},saveToServer:function(e,t){t===void 0&&(t=!0),this.syncRichTextEditors(),this.blurAllInputs();var i=this.model.get("submissionModel");if(t&&!this.checkBeforeSave(i))return null;var a=this.numInvalidWordCounts();return a>0?(d.alertSimpleError("Error: "+(1===a?"One":a)+" of your texts "+(1===a?"is":"are")+" over the word limit. Your submission was not saved. Reduce the number of words and try again."),null):(i.assessment.allowsExclusionFromCirculation()&&i.set("excludedFromCirculation",!n('[name="privacyAllowCirculation"]').is(":checked")),i.save())},showProgressIndicators:function(e){var t=n("#topContentToolbar #assessmentSave, #topContentToolbar #assessmentSubmit"),i=n("#bottomContentToolbar #assessmentSave, #bottomContentToolbar #assessmentSubmit");d.showLoadingIndicator(t,e,"topSubmittingLoader"),d.showLoadingIndicator(i,e,"bottomSubmittingLoader")},hideProgressIndicators:function(){var e=n("#topContentToolbar #assessmentSave, #topContentToolbar #assessmentSubmit"),t=n("#bottomContentToolbar #assessmentSave, #bottomContentToolbar #assessmentSubmit");d.hideLoadingIndicator(e,"topSubmittingLoader"),d.hideLoadingIndicator(t,"bottomSubmittingLoader")},save:function(t){var n=this;t.preventDefault();var i=this.saveToServer(t);i?(n.showProgressIndicators("Saving..."),i.done(function(){n.hideAllFieldErrors(),n.hideProgressIndicators(),e.app.vent.trigger("assessmentAlert",{type:"success",html:'Your draft was saved but <span class="hg-warning-text"><b><i>not</i></b> yet submitted</span>. <a href="'+p.submissionPreviewUrl(n.model.get("courseModel").get("id"),n.model.get("assessmentModel").get("id"),n.model.get("submissionModel").get("id"))+'" target="_blank">Review your work</a> to make sure everything looks OK.',stayVisible:!0})}).fail(function(e,t,i){n.hideProgressIndicators(),n.handleApiErrors(e,t,i,"Your submission was not saved.")})):e.log("Backbone validation failed during save.",this)},countBlanks:function(e){var t=e.get("fields"),a=0,o=0;return this.tinyMCE&&this.tinyMCE.editors&&(a=this.tinyMCE.editors.length),a+=n("#assessmentForm").find('input[type="text"]:visible:not([disabled])[data-modelbind^="submission"], textarea:visible:not([disabled])[data-modelbind^="submission"]').length,t&&i.each(t,function(e){e&&e.trim().length>0&&(o+=1)}),{answered:o,total:a}},checkBeforeSave:function(e){var t=this.countBlanks(e);return 0===t.answered?window.confirm("Warning: You are attempting to save a blank assignment.\n\nAre you sure ?"):!0},checkBeforeSubmit:function(e){var t=this.countBlanks(e);return 0===t.answered?window.confirm("Warning: You are attempting to submit a blank assignment.\n\nAre you sure ?"):t.answered<t.total?window.confirm("Warning: You are attempting to submit a partially-completed assignment.\n\nAre you sure ?"):!0},submit:function(t){var i=this;if(t.preventDefault(),this.syncRichTextEditors(),this.blurAllInputs(),this.checkBeforeSubmit(this.model.get("submissionModel"))){var a=this.saveToServer(t,!1);a?(i.showProgressIndicators("Submitting..."),a.pipe(function(){i.hideAllFieldErrors();var t=i.model.get("submissionModel");return n.post(t.url()+"/submit").done(function(n){i.hideAllFieldErrors(),t.set(n),i.trigger("showActionBar"),i.hideProgressIndicators(),e.app.vent.trigger("assessmentAlert",{type:"success",html:'Your work was submitted. <a href="'+p.submissionPreviewUrl(i.model.get("courseModel").get("id"),i.model.get("assessmentModel").get("id"),i.model.get("submissionModel").get("id"))+'" target="_blank">Review your work</a> to make sure everything looks OK.',stayVisible:!0})}).fail(function(e,t,n){i.trigger("showActionBar"),i.hideProgressIndicators(),i.handleApiErrors(e,t,n,"Your submission was not submitted.")})},function(e,t,n){i.trigger("showActionBar"),i.hideProgressIndicators(),i.handleApiErrors(e,t,n,"Your submission was not saved.")}).done(function(){i.authenticateSignatureIfNeeded()})):e.log("Backbone validation failed during submit.",this)}},authenticateSignatureIfNeeded:function(){var e=this,t=this.model.get("submissionModel");t.get("signatureAuthenticationStatus")===u.SIGNATURE_STATUS.AUTHENTICATION_ATTEMPT_ALLOWED&&e.openSignatureModal()},openSignatureModal:function(){var e=this.model.get("submissionModel"),n=new l("#coursera-signature-modal",{type:"hg",submissionid:e.id,url:t.sparkUrl("signature/modal_iframe")});n.open().always(function(){})}});return h});
define('templates/SubmissionShowViewHeader.hbs',[],function(){return function(e,t,n){n=n||e.helpers;var i,a,o="",r="function",s=this.escapeExpression,l=n.helperMissing;return o+='\n<h1 class="assessmentTitle">',i=t.assessment,i=null==i||i===!1?i:i.title,i=typeof i===r?i():i,o+=s(i)+'</h1>\n<div class="submissionProperties">\n  <div class="submissionPropertyLabel">Student: <span class="assessmentSubmissionAuthor">',i=t.submissionModel,a=n.author,i=a?a.call(t,i,{hash:{}}):l.call(t,"author",i,{hash:{}}),o+=s(i)+'</span></div>\n  <div class="submissionPropertyLabel">Last saved: <span class="saveTime">',a=n.saveTimeLocaleString,a?i=a.call(t,{hash:{}}):(i=t.saveTimeLocaleString,i=typeof i===r?i():i),o+=s(i)+"</span></div>\n</div>"}});
define('views/SubmissionShowView',["app/Assess","lib/Util","jquery","underscore","handlebars","views/SubmissionBaseView","templates/SubmissionShowViewHeader.hbs"],function(e,t,n,i,a,o,r){var s=o.extend({render:function(){var e=this,o=this.model.get("assessmentModel"),s=this.model.get("submissionModel");n.when(o.fetchPromise,s.fetchPromise).done(function(){e.model.set("saveTimeLocaleString",t.fromTimeStringToLocaleString(s.get("saveTime")));var n={editableSubmission:!1,shrinkLargeInstructions:!0,header:a.template(r)(e.serializeData()),isReview:!0},l=o.access.getBestStep();"submitting"===l?n=i.extend(n,{hideEvaluation:!0}):"results"===l&&(n=i.extend(n,{step:"results",realStep:"sharing"})),e.renderVariant(n)})}});return s});
define('views/SubmissionShareView',["app/Assess","lib/Util","backbone","marionette","views/SubmissionBaseView","routers/RoutingRules","jquery","underscore","handlebars"],function(e,t,n,i,a,o,r){var s=a.extend({render:function(){var e,t=o.submissionPreviewUrl(this.model.get("courseModel").get("id"),this.model.get("assessmentModel").get("id"),this.model.get("submissionModel").get("id"));this.model.get("submissionModel").get("excludedFromCirculation")?e="You marked your submission as private, so you cannot share your submission with other people.":(e='<p>You can share <a href="'+t+'">your submission</a>'+" with your classmates by copying and pasting the link below into a new thread in the forums.</p>",e+='<p><input id="mySubmissionShareURL" type="text" size="10" value="'+t+'" /></p>'),this.$el.html(e),this.$("#mySubmissionShareURL").click(function(){r(this).select()})}});return s});
define('controllers/SubmissionsController',["app/Assess","jquery","underscore","backbone","marionette","models/Submission","models/OverallEvaluation","views/SubmissionShowLayout","views/SubmissionEditView","views/SubmissionShowView","views/SubmissionShareView","views/ViewHelpers"],function(e,t,n,i,a,o,r,s,l,u,c,d){var p={parentLayout:null,showView:function(e){this.parentLayout.contentRegion.show(e)},viewModel:function(e,t,i){var a={};return e&&n.extend(a,{course:e.attributes,courseModel:e}),t&&n.extend(a,{assessment:t.attributes,assessmentModel:t}),i&&n.extend(a,{submission:i.attributes,submissionModel:i}),a},showSubmissionEditView:function(n,i,a){var o=this;t.when(i.fetchPromise,a.fetchPromise).done(function(){i.access.extractAccessFromXhr(i.fetchPromise);var t=new l(e.wrappedViewModel(o.viewModel(n,i,a))),r=function(){o.showActionBar({toolbars:["topContentToolbar","bottomContentToolbar"]},n,i,a)};t.on("showActionBar",function(){r()}),o.showView(t),r()})},index:function(i,a){var r,s=this;t.getJSON(e.API_BASE_URL+"assessments/"+a.get("id")+"/submissions").fail(function(e,t,n){d.alertAjaxError("Could not get your submission from the service.",e,t,n)}).done(function(t){if(t)if(t.length){var l=t[t.length-1];r=n.extend(new o(l),{assessment:a}),r.fetchPromise=r.fetch().fail(function(e,t,n){d.alertAjaxError("Could not get your submission from the service.",e,t,n)}),s.showSubmissionEditView(i,a,r)}else s.showSubmissionEditView(i,a,n.extend(new o,{assessment:a}));else e.logEvent("system.fatal","submissionsJson is not defined.")})},showActionBar:function(n,i,a,o){var r="",s="",l=t("<input>").attr("type","checkbox").attr("id","honorCode").addClass("honorCode"),u="In accordance with the Honor Code, I certify that my answers here are my own work, and that I have appropriately acknowledged all external sources (if any) that were used in this work.";o.get("submitTime")?(a.isResubmitAllowed()?(r+='<span style="color:green"><i class="icon-ok"></i> Submitted.</span>  You can still make changes and re-submit before the deadline.',s+='<a id="assessmentSubmit" href="#" role="button" class="hg-internal assessmentSubmit btn btn-primary">Re-submit for grading</a>'):(r+="Your work has been submitted.",s+=" "),l.attr("disabled","disabled").attr("checked","checked")):o.get("saveTime")&&!o.get("submitTime")&&(r+='<p><span class="hg-warning-text">NOTE:</span> You have saved, <i>but not submitted</i>, your work. If you do not submit your work before the deadline, you will not be allowed to evaluate the work of your peers and your own work will not be evaluated. <b>Don\'t wait until the last minute</b>, in case you have unforeseen problems such as power outages.',a.isResubmitAllowed()&&(r+=" Note that after you submit, you can still make changes and re-submit as long as it's before the deadline -- so <b>submit early</b>."),r+="</p>"),r+="<p><label>"+l[0].outerHTML+"&nbsp;"+u+"</label></p>",""===s&&(s='<a id="assessmentSave" href="#" role="button" class="hg-internal btn">Save draft</a><a disabled="disabled" id="assessmentSubmit" href="#" role="button" class="assessmentSubmit hg-internal btn disabled">Submit for grading</a>');var c="";c+='<div class="contentToolbarButtons">',c+='<div class="pull-left" style="text-align: left;">',c+=r,c+="</div>",c+='<div class="pull-right">',c+=s,c+="</div>",c+="</div>",c&&e.app.vent.trigger("updateContentToolbars",{toolbars:n.toolbars,html:c})},edit:function(e,t,i){var a=this,r=n.extend(new o({id:i}),{assessment:t});r.fetchPromise=r.fetch().fail(function(e,t,n){d.alertAjaxError("Could not get your submission from the service.",e,t,n)}).done(function(){a.showSubmissionEditView(e,t,r)})},show:function(i,a,l){this.parentLayout=new s,e.app.mainRegion.show(this.parentLayout);var u=this,c=n.extend(new o({id:l}),{assessment:a});c.fetchPromise=c.fetch().fail(function(e,t,n){d.alertAjaxError("Could not get the submission from the service.",e,t,n)}),t.when(c.fetchPromise,a.fetchPromise).done(function(){t.getJSON(e.API_BASE_URL+"assessments/"+a.get("id")+"/settings",function(t,o,s){a.access.extractAccessFromXhr(s);var l=u.viewModel(i,a,c);if("results"===a.access.getBestStep()){var d=n.extend(new r,{submission:c});d.fetch().done(function(){n.extend(l,{overallEvaluation:d.attributes,overallEvaluationModel:d}),u.showSubmissionShowView(e.wrappedViewModel(l))}).fail(function(){u.showSubmissionShowView(e.wrappedViewModel(l))})}else u.showSubmissionShowView(e.wrappedViewModel(l))})})},showSubmissionShowView:function(e){var t=new u(e);this.parentLayout.contentRegion.show(t)},share:function(i,a){var r,s=this;t.getJSON(e.API_BASE_URL+"assessments/"+a.get("id")+"/submissions").fail(function(e,t,n){d.alertAjaxError("Could not get your submission from the service.",e,t,n)}).done(function(l){if(l)if(l.length){var u=l[l.length-1];r=n.extend(new o(u),{assessment:a}),r.fetchPromise=r.fetch().fail(function(e,t,n){d.alertAjaxError("Could not get your submission from the service.",e,t,n)}),t.when(a.fetchPromise,r.fetchPromise).done(function(){var t=new c(e.wrappedViewModel(s.viewModel(i,a,r)));s.parentLayout.contentRegion.show(t)})}else e.Routing.redirect({courseId:i.id,assessmentId:a.id,submissionId:"new"});else e.logEvent("system.fatal","submissionsJson is not defined.")})}};return p});
define('models/Evaluation',["app/Assess","jquery","underscore","backbone","marionette","models/Submission"],function(e,t,n,i,a,o){var r=i.DeepModel.extend({keepInSync:!0,submission:null,getBaseUrl:function(){return e.API_BASE_URL},url:function(){return this.isNew()?(e.assert(this.submission,"this.submission undefined on evaluation "+this.id),this.submission.url()+"/evaluations"):this.getBaseUrl()+"evaluations/"+this.id},getSubmission:function(){return this.submission}});return r.prototype.fetch=function(){var n,i=this;return"preview"===this.id?(i.set(i.parse({submissionId:"preview"})),n=t.Deferred().resolve().promise()):n=this.constructor.__super__.fetch.apply(this,arguments),n.pipe(function(){var t=i.submission||new o({id:i.get("submissionId")});return t.fetch().done(function(){i.submission=t}).fail(function(){e.error("Can't get the submission for the evaluation.")})})},r});
define('models/Training',["app/Assess","lib/Util","jquery","underscore","backbone","marionette","models/Evaluation"],function(e,t,n,i,a,o,r){var s=a.Model.extend({trainingSet:null,evaluation:null,fetchPromise:null,getBaseUrl:function(){return this.trainingSet?this.trainingSet.getBaseUrl():""},url:function(){return e.assert(this.trainingSet,"this.trainingSet undefined on trainingSet "+this.id),this.isNew()?this.trainingSet.url()+"/trainings":this.trainingSet.url()+"/trainings/"+this.id},fetchEvaluation:function(){var e=this;return e.evaluation||(e.evaluation=new r({id:e.get("evaluationId")}),e.fetchPromise=e.evaluation.fetch()),t.ifOrWhen(null===e.fetchPromise,e.fetchPromise)}});return s.prototype.fetch=e.DEV_STANDALONE?function(e){e=e?i.clone(e):{};var t=this,o=e.success;return e.success=function(n,i,a){return t.set(t.parse(n,a),e)?(o&&o(t,n),void 0):!1},e.error=a.wrapError(e.error,t,e),e.success.call(void 0,{id:"PEERGRADING_FROM_FETCH",evaluationId:"EVALUATION_FROM_FETCH",required:!0,lastRequired:!0},"success",null),this.fetchPromise=n.Deferred().resolve(null,null,{status:200}).promise()}:function(e){return this.fetchPromise=a.Model.prototype.fetch.call(this,e)},s});
define('models/TrainingSet',["app/Assess","jquery","underscore","backbone","marionette","models/Training"],function(e,t,n,i,a,o){var r=i.Collection.extend({model:o}),s=i.Model.extend({assessment:null,initialize:function(){var e=this,t=new r;this.set("items",t),t.on("reset",function(){t.each(function(t){t.trainingSet=e})}),t.on("add",function(t){t.trainingSet=e})},getBaseUrl:function(){return this.assessment?this.assessment.getBaseUrl():""},url:function(){return this.isNew()?(e.assert(this.assessment,"this.assessment undefined on trainingSet "+this.id),this.assessment.url()+"/trainingSets/latest"):this.getBaseUrl()+"trainingSets/"+this.id},parse:function(e){return this.get("items").reset(e.items),delete e.items,e}});return e.DEV_STANDALONE&&(s.prototype.fetch=function(e){e=e?n.clone(e):{};var a=this,o=e.success;return e.success=function(t,n,i){return a.set(a.parse(t,i),e)?(o&&o(a,t),void 0):!1},e.error=i.wrapError(e.error,a,e),e.success.call(void 0,{id:"TRAININGSET_FROM_FETCHLIST",items:[{id:"TRAINING_FROM_FETCHLIST",evaluationId:"EVALUATION_FROM_FETCHLIST",required:!0,lastRequired:!1},{id:"TRAINING_FROM_FETCHLIST2",evaluationId:"EVALUATION_FROM_FETCHLIST",required:!0,lastRequired:!0},{id:"TRAINING_FROM_FETCHLIST3",evaluationId:"EVALUATION_FROM_FETCHLIST",required:!1,lastRequired:!1}],status:"pass"},"success",null),t.Deferred().resolve(null,null,{status:200}).promise()}),s});
define('templates/TrainingSetView.hbs',[],function(){return function(e,t,n,i,a){function o(){return"\n      <th>The grade you gave</th>"}function r(e,t,i){var a,o,r="";return r+='\n    <tr>\n      <td><a href="',a=i.trainingSet,a=null==a||a===!1?a:a.id,o=n.trainingSetPath,a=o?o.call(e,a,{hash:{}}):d.call(e,"trainingSetPath",a,{hash:{}}),r+=p(a)+"/trainings/",o=n.id,o?a=o.call(e,{hash:{}}):(a=e.id,a=typeof a===h?a():a),r+=p(a)+'" class="hg-internal">Exercise ',o=n.index,o?a=o.call(e,{hash:{}}):(a=e.index,a=typeof a===h?a():a),r+=p(a)+"</a></td>",a=i.displayGrade,a=n["if"].call(e,a,{hash:{},inverse:f.noop,fn:f.programWithDepth(s,t,i)}),(a||0===a)&&(r+=a),r+="\n      <td>",o=n.statusOrTodo,a=o?o.call(e,e,{hash:{}}):d.call(e,"statusOrTodo",e,{hash:{}}),(a||0===a)&&(r+=a),r+="</td>\n    </tr>"}function s(e,t,i){var a,o,r,s,l="";return l+="\n      <td>",a=e.evaluation,o={},r=i.assessmentModel,o.assessment=r,s=n.studentGradingProgress,a=s?s.call(e,a,{hash:o}):d.call(e,"studentGradingProgress",a,{hash:o}),(a||0===a)&&(l+=a),l+="</td>"}n=n||e.helpers;var l,u,c="",d=n.helperMissing,p=this.escapeExpression,h="function",f=this;return c+='\n<h1 class="pageTitle">Learn to evaluate this assignment</h1>\n<table id="trainingSet" class="setView table table-striped">\n  <thead>\n    <tr>\n      <th></th>',l=t.displayGrade,l=n["if"].call(t,l,{hash:{},inverse:f.noop,fn:f.program(1,o,a)}),(l||0===l)&&(c+=l),c+="\n      <th>Your training progress</th>\n    </tr>\n  </thead>\n  <tbody>",l=t.trainings,u=n.eachWithIndex,l=u?u.call(t,l,{hash:{},inverse:f.noop,fn:f.programWithDepth(r,a,t)}):d.call(t,"eachWithIndex",l,{hash:{},inverse:f.noop,fn:f.programWithDepth(r,a,t)}),(l||0===l)&&(c+=l),c+='\n  </tbody>\n</table>\n<div id="bottomContentToolbar" class="contentToolbar form-actions hide"></div>'}});
define('views/TrainingSetView',["app/Assess","jquery","underscore","backbone","marionette","modelbinding","handlebars","views/BaseView","models/TrainingSet","templates/TrainingSetView.hbs"],function(e,t,n,i,a,o,r,s,l,u){r.registerHelper("statusOrTodo",function(e){var t=e.get("feedback")&&e.get("feedback").status;switch(t){case"pass":t='<i class="icon-ok" style="color:green"></i>';break;case"fail":t='<i class="icon-remove" style="color:red"></i>'}return"ongoing"==t?"?":t});var c=s.extend({template:function(){return r.template(u)},initialize:function(){var t=this;r.registerHelper("trainingSetPath",function(n){return e.BACKBONE_ROOT+"courses/"+t.model.get("assessmentModel").course.id+"/assessments/"+t.model.get("assessmentModel").id+"/trainingSets/"+n})},onShow:function(){this.$el.hide().fadeIn()}});return c});
define('templates/TrainingSubmitSuccess.hbs',[],function(){return function(e,t,n){n=n||e.helpers;var i,a,o="",r="function",s=this.escapeExpression;return o+='\n<p>\n   \n  Your work was submitted.<a href="',a=n.buttonLink,a?i=a.call(t,{hash:{}}):(i=t.buttonLink,i=typeof i===r?i():i),o+=s(i)+'" role="button" class="hg-internal btn btn-primary">',a=n.buttonText,a?i=a.call(t,{hash:{}}):(i=t.buttonText,i=typeof i===r?i():i),o+=s(i)+"</a>\n</p>"}});
define('views/TrainingEditView',["app/Assess","jquery","underscore","backbone","marionette","modelbinding","bootstrap_tooltip","models/Evaluation","views/SubmissionBaseView","handlebars","templates/TrainingSubmitSuccess.hbs"],function(e,t,n,i,a,o,r,s,l){var u=l.extend({events:function(){return n.extend({},l.prototype.events,{"click #assessmentSave":"save","click #assessmentSubmit":"submit"})},render:function(){this.renderVariant(n.extend({step:"training",title:"Training Exercise "+(this.model.get("training").id+1),shrinkLargeInstructions:!0},this.model.get("evaluationModel").get("submitTime")&&{}||{editableEvaluation:this.model.get("assessmentModel").access.isStepWritable("training")}))},saveToServer:function(){return this.syncRichTextEditors(),this.blurAllInputs(),this.model.get("evaluationModel").save()},save:function(t){var i=this;t.preventDefault();var a=this.saveToServer(t);a?a.done(function(){i.hideAllFieldErrors(),e.app.vent.trigger("assessmentAlert",{type:"success",html:'Your draft was saved but <span class="hg-warning-text"><b><i>not</i></b> yet submitted</span>.'})}).fail(n.bind(i.handleApiErrors,i)):e.log("Backbone validation failed during save.",this)},submit:function(i){var a=this;i.preventDefault();var o=this.saveToServer(i);o?o.done(function(){a.hideAllFieldErrors();var i=a.model.get("trainingModel");t.post(i.url()+"/submit").pipe(null,function(n){return e.DEV_STANDALONE?t.Deferred().resolve().promise():n.promise()}).pipe(function(){return i.fetch()}).pipe(function(){return i.evaluation.fetch()}).done(function(){a.hideAllFieldErrors();var e=t("#submissionToolbar").stop(!0,!0).fadeOut({duration:300,queue:!1}).slideUp(300).promise();a.trigger("submit",function(){e.done(function(){a.insertTrainingFeedback()})})}).fail(n.bind(a.handleApiErrors,a))}).fail(n.bind(a.handleApiErrors,a)):e.log("Backbone validation failed during submit.",this)}});return u});
define('controllers/TrainingSetsController',["app/Assess","lib/Util","jquery","underscore","backbone","marionette","models/TrainingSet","models/Training","views/TrainingSetView","views/TrainingEditView","views/ViewHelpers"],function(e,t,n,i,a,o,r,s,l,u,c){var d={parentLayout:null,trainingSet:null,modelize:function(){var e=Array.prototype.slice.call(arguments),t=e.shift(),n=e.shift(),i=e.shift();return this.fetchTrainingSet(n,i),[t,n,this.trainingSet].concat(e)},modelizeTrainingSet:function(e,t,n){this.trainingSet||(this.trainingSet=this.modelize(e,t,n)[2])},showView:function(e){this.parentLayout.contentRegion.show(e)},showTrainingEditView:function(t,n,a,o,s,l){var d=this;n.fetchPromise.done(function(){var h=new u(e.wrappedViewModel({returnUrl:e.Routing.redirectPath({courseId:t.id,assessmentId:n.id,trainingSetId:a}),assessment:n.attributes,training:o.attributes,evaluation:s.attributes,submission:l.attributes,assessmentModel:n,trainingModel:o,evaluationModel:s,submissionModel:l}));h.on("submit",function(o){if(!d.trainingSet)return e.logEvent("fatal","TrainingSet is missing on submit."),void 0;var s=i.extend(new r({id:a}),{assessment:n});s.fetch().done(function(){d.trainingSet.set("status",s.get("status")),d.trainingSet.set("lastSet",s.get("lastSet"));for(var e=d.trainingSet.get("items"),t=s.get("items"),n=0,i=e.size(),a=t.size();i>n&&a>n;++n)e.at(n).set("feedback",t.at(n).get("feedback"))}).fail(function(e,t,n){c.alertAjaxError("Could not get a training status from the service.  Please try again later.",e,t,n)}).always(function(){d.showActionBar({toolbars:["topContentToolbar","bottomContentToolbar"]},t,n,a),i.isFunction(o)&&o.call()})}),d.showView(h)})},showTrainingSetView:function(t,n){var i=this;t.fetchPromise.done(function(){var a=new l(e.wrappedViewModel({displayGrade:t.isDisplayGradeEnabled(),trainingSet:n.attributes,trainings:n.get("items"),assessmentModel:t}));i.showView(a)})},index:function(e,t,n){var i=this;this.updateTrainingSet(e,t,n).always(function(){i.showTrainingSetView(t,i.trainingSet),i.showActionBar({toolbars:"bottomContentToolbar"},e,t,n)})},isTrainingFetchable:function(e){switch(e.get("status")){case"ongoing":return!0;case"pass":return e.get("items").size()<this.trainingSet.get("size");case"fail":return!1}},updateTrainingSet:function(e,n,i){var a=this;return this.fetchTrainingSet(n,i).pipe(function(){var e,n=a.trainingSet.get("items"),i=!1;return 0===n.size()&&a.trainingSet.get("size")>0?i=!0:(e=n.at(n.size()-1),e.evaluation.get("submitTime")&&a.isTrainingFetchable(a.trainingSet)&&(i=!0)),i&&(e=a.fetchIndexedTrainingAndReturn(n.size())),t.ifOrWhen(!i,i&&e.fetchPromise.pipe(function(){return e.fetchEvaluation()}).done(function(){n.push(e)})).fail(function(e,t,n){c.alertAjaxError("Could not get a new task from the service.  Please try again later.",e,t,n)})}).fail(function(e,t,n){c.alertAjaxError("Could not get a list of tasks from the service.  Please try again later.",e,t,n)})},showActionBar:function(t,n,a){var o=i.isArray(t.toolbars)?"next ":"",r="";if(i.isArray(t.toolbars)){var s=this.trainingSet.get("items").last().get("feedback");s&&(r+="<p>Your evaluation"+("pass"==s.status?" was excellent":" could be better")+".  Look for feedback embedded in the page.</p><hr />")}switch(this.trainingSet.get("status")){case"ongoing":r+='<a class="hg-internal btn btn-primary" href="'+e.Routing.redirectPath({courseId:n.id,assessmentId:a.id,trainingSetId:this.trainingSet.id})+'/next"><i class="icon-edit"></i> Do '+o+"exercise</a>";break;case"pass":r+="<p>Good job, you passed the training.  You may go on to peer evaluation.</p>",this.trainingSet.get("items").size()<this.trainingSet.get("size")&&(r+='<a class="hg-internal btn" href="'+e.Routing.redirectPath({courseId:n.id,assessmentId:a.id,trainingSetId:this.trainingSet.id})+'/next"><i class="icon-plus"></i> Do '+o+"exercise (optional)</a>"),r+='<a class="hg-internal btn btn-primary" href="'+e.Routing.redirectPath({courseId:n.id,assessmentId:a.id,peerGradingSetId:null})+'"><i class="icon-arrow-right"></i> Go on to peer evaluation</a>';break;case"fail":this.trainingSet.get("lastSet")?(r+="<p>You did not pass training.  It's important for peer evaluations to be done carefully.</p>",r+='<a class="hg-internal btn btn-primary" href="'+e.Routing.redirectPath({courseId:n.id,assessmentId:a.id,peerGradingSetId:null})+'"><i class="icon-arrow-right"></i> Go on to peer evaluation</a>'):r+='<a class="hg-internal btn btn-primary" href="'+e.Routing.redirectPath({courseId:n.id,assessmentId:a.id,trainingSetId:this.trainingSet.id})+'/next"><i class="icon-refresh"></i> Try another round</a>'}r&&e.app.vent.trigger("updateContentToolbars",{toolbars:t.toolbars,html:r})},next:function(i,a,o){var r=this;this.fetchTrainingSet(a,o).done(function(){var s,l=r.trainingSet.get("items");switch(r.trainingSet.get("status")){case"ongoing":case"pass":var u=!1;if(0===l.size()){if(0===r.trainingSet.get("size"))return c.alertAjaxError("Got an empty training set.  Please try again later."),void 0;u=!0}else s=l.at(l.size()-1),s.evaluation.get("submitTime")&&r.isTrainingFetchable(r.trainingSet)&&(u=!0);u&&(s=r.fetchIndexedTrainingAndReturn(l.size())),t.ifOrWhen(!u,u&&s.fetchPromise.pipe(function(){return s.fetchEvaluation()}).done(function(){l.push(s)})).done(function(){e.Routing.redirect({courseId:i.id,assessmentId:a.id,trainingSetId:o,trainingId:s.id})}).fail(function(e,t,n){c.alertAjaxError("Could not get a new task from the service.  Please try again later.",e,t,n)});break;case"fail":r.trainingSet.get("lastSet")?e.Routing.redirect({courseId:i.id,assessmentId:a.id,peerGradingSetId:null}):n.post(a.url()+"/trainingSets/new").done(function(){r.trainingSet=null,e.Routing.redirect({courseId:i.id,assessmentId:a.id,trainingSetId:null})}).fail(function(e,t,n){c.alertAjaxError("Could not get a new training set from the service.  Please try again later.",e,t,n)})}})},edit:function(e,n,a,o){var r,l=this,u=null;t.ifOrWhen(!this.trainingSet||!this.trainingSet.fetchPromise,this.trainingSet&&this.trainingSet.fetchPromise.done(function(){r=l.trainingSet.get("items").find(function(e){return e.id===parseInt(o,10)})})).always(function(){r===void 0&&(l.modelizeTrainingSet(e,n,a),r=i.extend(new s({id:o}),{trainingSet:l.trainingSet}),u=r.fetch()),t.ifOrWhen(null===u,u&&u.pipe(function(){return r.fetchEvaluation()})).done(function(){l.showTrainingEditView(e,n,a,r,r.evaluation,r.evaluation.submission)}).fail(function(e,t,n){c.alertAjaxError("Could not get the task from the service.  Please try again later.",e,t,n)})})},fetchTrainingSet:function(t,a){var o=this;return this.trainingSet&&null!==this.trainingSet.fetchPromise?this.trainingSet.fetchPromise:(this.trainingSet=i.extend(new r({id:a}),{assessment:t}),this.trainingSet.fetchPromise=this.trainingSet.fetch().pipe(function(){return n.when.apply(null,o.trainingSet.get("items").reduce(function(e,t){return e.push(t.fetchEvaluation()),e},[]))}).fail(function(){e.logEvent("system.fatal","Could not get trainingSet "+a)}))},fetchTrainings:function(e,t){return this.fetchTrainingSet(e,t)},fetchIndexedTrainingAndReturn:function(e){var t=this,n=i.extend(new s({id:e}),{trainingSet:t.trainingSet});return n.fetchPromise=n.fetch(),n}};return d});
define('models/PeerGrading',["app/Assess","lib/Util","jquery","underscore","backbone","marionette","models/Evaluation"],function(e,t,n,i,a,o,r){var s=a.Model.extend({peerGradingSet:null,evaluation:null,fetchPromise:null,getBaseUrl:function(){return this.peerGradingSet?this.peerGradingSet.getBaseUrl():""},url:function(){return e.assert(this.peerGradingSet,"this.peerGradingSet undefined on peerGradingSet "+this.id),this.isNew()?this.peerGradingSet.url()+"/peerGradings":this.peerGradingSet.url()+"/peerGradings/"+this.id},fetchEvaluation:function(){var e=this;return e.evaluation||(e.evaluation=new r({id:e.get("evaluationId")}),e.fetchPromise=e.evaluation.fetch()),t.ifOrWhen(null===e.fetchPromise,e.fetchPromise)}});return s.prototype.fetch=function(e){return this.fetchPromise=a.Model.prototype.fetch.call(this,e)},s});
define('models/PeerGradingSet',["app/Assess","jquery","underscore","backbone","marionette","models/PeerGrading"],function(e,t,n,i,a,o){var r=i.Collection.extend({model:o}),s=i.Model.extend({assessment:null,initialize:function(){var e=this,t=new r;this.set("items",t),t.on("reset",function(){t.each(function(t){t.peerGradingSet=e})}),t.on("add",function(t){t.peerGradingSet=e})},fetch:function(){return"preview"===this.id?(this.set(this.parse({id:"preview",items:[{id:0,peerGradingSetId:"preview",evaluationId:"preview",required:1,lastRequired:1}],numberOfRequired:1,numberOfRequiredLeft:0})),this.get("items").at(0).fetchEvaluation()):this.constructor.__super__.fetch.apply(this,arguments)},getBaseUrl:function(){return this.assessment?this.assessment.getBaseUrl():""},url:function(){return this.isNew()?(e.assert(this.assessment,"this.assessment undefined on peerGradingSet "+this.id),this.assessment.url()+"/peerGradingSets/latest"):this.getBaseUrl()+"peerGradingSets/"+this.id},parse:function(e){return this.get("items").reset(e.items),delete e.items,e}});return s});
define('templates/PeerGradingSetView.hbs',[],function(){return function(e,t,n,i,a){function o(){return"\n        The grade you gave\n        "}function r(){return"\n        Progress\n        "}function s(e,t,i){var a,o,r,s,c="";return c+='\n    <tr>\n      <td><a href="',a=i.peerGradingSet,a=null==a||a===!1?a:a.id,s=n.peerGradingSetPath,a=s?s.call(e,a,{hash:{}}):h.call(e,"peerGradingSetPath",a,{hash:{}}),c+=f(a)+"/peerGradings/",s=n.id,s?a=s.call(e,{hash:{}}):(a=e.id,a=typeof a===m?a():a),c+=f(a)+'" class="hg-internal">Student ',s=n.index,s?a=s.call(e,{hash:{}}):(a=e.index,a=typeof a===m?a():a),c+=f(a)+"</a></td>\n      <td>\n        ",a=e.attributes,a=null==a||a===!1?a:a.required,a=n["if"].call(e,a,{hash:{},inverse:g.program(8,u,t),fn:g.program(6,l,t)}),(a||0===a)&&(c+=a),c+="\n      </td>\n      <td>",a=e.evaluation,o={},r=i.assessmentModel,o.assessment=r,s=n.studentGradingProgress,a=s?s.call(e,a,{hash:o}):h.call(e,"studentGradingProgress",a,{hash:o}),(a||0===a)&&(c+=a),c+="</td>\n    </tr>"}function l(){return"\n        "}function u(){return"\n        (optional)\n        "}n=n||e.helpers;var c,d,p="",h=n.helperMissing,f=this.escapeExpression,m="function",g=this;return p+='\n<h1 class="pageTitle">Evaluate the submissions of some classmates</h1>\n<table id="peerGradingSet" class="setView table table-striped">\n  <thead>\n    <tr>\n      <th></th>\n      <th style="width:100px"></th>\n      <th>\n        ',c=t.displayGrade,c=n["if"].call(t,c,{hash:{},inverse:g.program(3,r,a),fn:g.program(1,o,a)}),(c||0===c)&&(p+=c),p+="\n      </th>\n    </tr>\n  </thead>\n  <tbody>",c=t.peerGradings,d=n.eachWithIndex,c=d?d.call(t,c,{hash:{},inverse:g.noop,fn:g.programWithDepth(s,a,t)}):h.call(t,"eachWithIndex",c,{hash:{},inverse:g.noop,fn:g.programWithDepth(s,a,t)}),(c||0===c)&&(p+=c),p+='\n  </tbody>\n</table>\n<div id="bottomContentToolbar" class="contentToolbar form-actions hide"></div>'}});
define('views/PeerGradingSetView',["app/Assess","lib/Util","jquery","underscore","backbone","marionette","modelbinding","handlebars","views/BaseView","models/PeerGradingSet","templates/PeerGradingSetView.hbs"],function(e,t,n,i,a,o,r,s,l,u,c){s.registerHelper("studentGradingProgress",function(e,n){return n.hash.assessment.isDisplayGradeEnabled()?e.get("submitTime")?e.get("grade")!==void 0?t.round(e.get("grade"),1):"-":"?":e.get("submitTime")?"Done":"?"});var d=l.extend({template:function(){return s.template(c)},initialize:function(){var t=this;s.registerHelper("peerGradingSetPath",function(n){return e.BACKBONE_ROOT+"courses/"+t.model.get("assessmentModel").course.id+"/assessments/"+t.model.get("assessmentModel").id+"/peerGradingSets/"+n})},onShow:function(){this.$el.hide().fadeIn()}});return d});
define('templates/PeerGradingSubmitSuccess.hbs',[],function(){return function(e,t,n){n=n||e.helpers;var i,a,o="",r="function",s=this.escapeExpression;return o+='\n<p>\n   \n  Your work was submitted.<a href="',a=n.buttonLink,a?i=a.call(t,{hash:{}}):(i=t.buttonLink,i=typeof i===r?i():i),o+=s(i)+'" role="button" class="hg-internal btn btn-primary">',a=n.buttonText,a?i=a.call(t,{hash:{}}):(i=t.buttonText,i=typeof i===r?i():i),o+=s(i)+"</a>\n</p>"}});
define('views/PeerGradingEditView',["app/Assess","jquery","underscore","backbone","marionette","modelbinding","models/Evaluation","views/SubmissionBaseView","routers/RoutingRules","handlebars","templates/PeerGradingSubmitSuccess.hbs"],function(e,t,n,i,a,o,r,s,l){var u=s.extend({events:function(){return n.extend({},s.prototype.events,{"click #assessmentGoToAntecedent":"editAntecedent","click #assessmentGoToSubsequent":"editSubsequent","click #assessmentSave":"save","click #assessmentSubmit":"submit"})},render:function(){var e=this.model.get("assessmentModel");if(this.renderVariant({step:"peerGrading",submissionAuthor:"Student "+(this.model.get("peerGrading").id+1),shrinkLargeInstructions:!0,editableEvaluation:e.access.isStepWritable("peerGrading")}),"results"===e.access.getBestStep()&&e.isSharingEnabled()&&!this.model.get("submissionModel").get("excludedFromCirculation")){var n=l.submissionPreviewUrl(this.model.get("courseModel").get("id"),e.get("id"),this.model.get("submissionModel").get("id")),i="You can share this submission with your classmates with this link: ";i+='<input id="mySubmissionShareURL" type="text" size="10" value="'+n+'" />',this.$("#assessmentHead").append('<div class="alert alert-info">'+i+"</div>"),this.$("#mySubmissionShareURL").click(function(){t(this).select()})}},saveToServer:function(){return this.syncRichTextEditors(),this.blurAllInputs(),this.model.get("evaluationModel").save()},editAntecedent:function(t){var n=this;t.preventDefault(),e.Routing.redirect({courseId:n.model.get("assessmentModel").course.id,assessmentId:n.model.get("assessmentModel").id,peerGradingSetId:n.model.get("peerGradingSet").id,peerGradingId:n.model.get("peerGradingModel").id},"/antecedent")},editSubsequent:function(t){var n=this;t.preventDefault(),e.Routing.redirect({courseId:n.model.get("assessmentModel").course.id,assessmentId:n.model.get("assessmentModel").id,peerGradingSetId:n.model.get("peerGradingSet").id,peerGradingId:n.model.get("peerGradingModel").id},"/subsequent")},save:function(t){var i=this;t.preventDefault();var a=this.saveToServer(t);a?a.done(function(){i.hideAllFieldErrors(),e.app.vent.trigger("assessmentAlert",{type:"success",html:'Your draft was saved but <span class="hg-warning-text"><b><i>not</i></b> yet submitted</span>.'})}).fail(n.bind(i.handleApiErrors,i)):e.log("Backbone validation failed during save.",this)},submit:function(i){var a=this;i.preventDefault();var o=this.saveToServer(i);o?o.done(function(){a.hideAllFieldErrors();var i=a.model.get("peerGradingModel");t.post(i.url()+"/submit").pipe(function(){return i.evaluation.fetch()}).done(function(){t("#submissionToolbar").stop(!0,!0).fadeOut({duration:300,queue:!1}).slideUp(300),a.trigger("updateActionBar"),e.app.vent.trigger("assessmentAlert",{type:"success",html:"Your work was submitted."})}).fail(n.bind(a.handleApiErrors,a))}).fail(n.bind(a.handleApiErrors,a)):e.log("Backbone validation failed during submit.",this)}});return u});
define('controllers/PeerGradingSetsController',["app/Assess","lib/Util","jquery","underscore","backbone","marionette","models/PeerGradingSet","models/PeerGrading","views/PeerGradingSetView","views/PeerGradingEditView","views/ViewHelpers"],function(e,t,n,i,a,o,r,s,l,u,c){var d={parentLayout:null,peerGradingSet:null,modelize:function(){var e=Array.prototype.slice.call(arguments),t=e.shift(),n=e.shift(),a=e.shift();return this.peerGradingSet||(this.peerGradingSet=i.extend(new r({id:a}),{assessment:n}),this.peerGradingSet.fetchPromise=this.peerGradingSet.fetch()),[t,n,this.peerGradingSet].concat(e)},modelizePeerGradingSet:function(e,t,n){this.peerGradingSet||(this.peerGradingSet=this.modelize(e,t,n)[2])},isDoneWithRequired:function(e){return 0===e.get("numberOfRequiredLeft")},numberOfRequired:function(e){return e.get("numberOfRequired")},numberOfRequiredDone:function(e){return i.reduce(e.get("items"),function(e,t){return e+(t.get("required")&&t.evaluation.get("submitTime")?1:0)},0)},isDonePreviewing:function(e){return e.get("items").size()===e.get("numberOfRequired")},showView:function(e){this.parentLayout.contentRegion.show(e)},showPeerGradingEditView:function(t,n,i,a,o,r){var s=this;n.fetchPromise.done(function(){var l=new u(e.wrappedViewModel({returnUrl:e.Routing.redirectPath({courseId:t.id,assessmentId:n.id,peerGradingSetId:i.id}),assessment:n.attributes,course:t.attributes,peerGrading:a.attributes,evaluation:o.attributes,submission:r.attributes,assessmentModel:n,courseModel:t,peerGradingSet:i,peerGradingModel:a,evaluationModel:o,submissionModel:r})),c=function(e){s.updateActionBar({init:e,toolbars:["topContentToolbar","bottomContentToolbar"]},t,n,s.peerGradingSet,a)};l.on("updateActionBar",function(){s.updatePeerGradingSet(t,n,i.id).always(function(){c()})}),s.showView(l),c(!0)})},showPeerGradingSetView:function(t,n){var i=this;t.fetchPromise.done(function(){var a=new l(e.wrappedViewModel({displayGrade:t.isDisplayGradeEnabled(),peerGradingSet:n.attributes,peerGradings:n.get("items"),assessmentModel:t}));i.showView(a)})},index:function(e,t,n){var i=this;this.updatePeerGradingSet(e,t,n).always(function(){i.showPeerGradingSetView(t,i.peerGradingSet),i.updateActionBar({toolbars:"bottomContentToolbar"},e,t,i.peerGradingSet)})},updatePeerGradingSet:function(e,n,i){var a=this;return this.peerGradingSet&&null!==this.peerGradingSet.fetchPromise&&"pending"!==this.peerGradingSet.fetchPromise.state()&&(this.peerGradingSet.fetchPromise=null),this.fetchPeerGradingSet(n,i).pipe(function(){var e,n=a.peerGradingSet.get("items"),i=!1;return 0===n.size()?i=!0:a.numberOfRequiredDone(a.peerGradingSet)!==n.length||a.isDoneWithRequired(a.peerGradingSet)||(i=!0),i&&(e=a.fetchIndexedPeerGradingAndReturn(n.size())),t.ifOrWhen(!i,e&&e.fetchPromise.pipe(function(){return e.fetchEvaluation()}).done(function(){n.push(e)})).fail(function(e,t,n){c.alertAjaxError("Could not get a new task from the service.  Please try again later.",e,t,n)})}).fail(function(e,t,n){c.alertAjaxError("Could not get a list of tasks from the service.  Please try again later.",e,t,n)})},updateActionBar:function(t,n,i,a,o){var r=!!o,s=i.isStepEnabled("selfGrading"),l=a.get("items"),u=l.size()>0?l.at(l.size()-1):null,c="",d="",h=this.isDoneWithRequired(a);h&&!s&&(r?o:u).evaluation.get("submitTime")&&(c+="<p>Congratulations on finishing this assessment. To see your results, come back afer the evaluation deadline has passed.</p>");var p=u&&!u.get("required")&&u.evaluation.get("submitTime");r&&(d+=o.evaluation.get("submitTime")?'<span style="color:green"><i class="icon-ok" style="color:green"></i> Submitted</span>&nbsp; <a id="assessmentSubmit" href="#" role="button" class="hg-internal btn">Re-submit evaluation</a>':'<a id="assessmentSave" href="#" role="button" class="hg-internal btn">Save draft</a><a id="assessmentSubmit" href="#" role="button" class="hg-internal btn btn-primary">Submit evaluation</a>'),!h&&r&&(1===this.numberOfRequired(a)||(o.id===this.numberOfRequired(a)-1?c+='<p><a class="hg-internal btn" href="'+e.Routing.redirectPath({courseId:n.id,assessmentId:i.id,peerGradingSetId:a.id,peerGradingId:0})+'"><i class="icon-fast-backward"></i> Go back to first submission</a></p>':this.isDonePreviewing(a)||(c+='<a class="hg-internal btn" href="'+e.Routing.redirectPath({courseId:n.id,assessmentId:i.id,peerGradingSetId:a.id,peerGradingId:o.id+1})+'"><i class="icon-step-forward"></i> Preview next submission</a>'+'&nbsp;&nbsp;<div class="alert alert-info" style="display: inline-block; vertical-align: top">'+"You are urged to preview the work of all "+this.numberOfRequired(a)+" of your peers before you start submitting your required evaluations.<br />"+'<b>Remember</b> to click the "Submit Evaluation" button after <i>each</i> time that you fill out'+" an evaluation.</div>")));var f=a.get("numberOfRequiredLeft");f>0&&(c+='</div><div class="pull-left" style="text-align: left; clear: both">',c+='<div class="hg-peergrading-counter">'+f+" remaining of "+this.numberOfRequired(a)+" required evaluation"+(this.numberOfRequired(a)>1?"s":"")+"</div>"),(!r||o.evaluation.get("submitTime"))&&(d+='<a class="hg-internal btn'+(h&&s?"":" btn-primary")+'" href="'+e.Routing.redirectPath({courseId:n.id,assessmentId:i.id,peerGradingSetId:a.id})+'/next">'+(h&&u.evaluation.get("submitTime")?'<i class="icon-plus"></i> Evaluate another student (optional but useful)':'<i class="icon-edit"></i> Evaluate next student')+"</a>"),h&&s&&(!u||u.evaluation.get("submitTime"))&&(i.isDisplayGradeEnabled()&&i.isIncompletePeerGradingPenaltyEnabled()&&(c+="You should now do your required self-valuation.  Skipping this step will result in a grade penalty."),d+='<a class="hg-internal btn btn-primary" href="'+e.Routing.redirectPath({courseId:n.id,assessmentId:i.id,selfGradingSetId:null})+'"><i class="icon-arrow-right"></i> Go on to self-evaluation</a>'),p&&(c+="You've evaluated "+l.size()+" submissions! <b>"+this.randomPraise(l.size())+"</b> Want to evaluate another one?");var m="";m+='<div class="contentToolbarButtons">',r||""!==c&&""!==d?(m+='<div class="pull-left" style="text-align: left;">',m+=c,m+="</div>",m+='<div class="pull-right">',m+=d,m+="</div>"):m+=c+d,m+="</div>",e.app.vent.trigger("updateContentToolbars",{toolbars:t.toolbars,html:m})},randomPraise:function(e){var t=["Great!","Cool!","Unbelievable work!","Way to go!","You've outdone yourself!","Amazing effort!","Breathtaking!","Keep up the good work!","You should be proud!","Stupendous!","You made it happen!","Good for you!","Extra special work!","You're tops!","Remarkable!","You're the greatest!","You're so kind!","Magnificent!","Outstanding effort!","Nice one!","Incredible!","Great job!","That's very kind!","You rock!","You're very patient!","Super duper!","Hats off to you!","Lovely!","Phenomenal!","Two thumbs up!","Terrific!","Marvelous!","Bravo!","Wonderful!","First rate work!","Sensational!","Awesome!","Super job!","Well done!","You go the extra mile!","Wow!","You're amazing!","You're a shining star!","Sweet!","I'm impressed!","You're a champ!","Thanks for helping!","You've earned my respect!","Neat work!","Right on!","Wicked!","Stunning!","A job well done!","Radical!","Wonderful!","Great dedication!","Spectacular!","I like it!","Superb!","Excellent!","You've got it!","Outstanding performance!","Your help counts!","Exceptional!","You're special!","Fantastic work!","Very good!","You made the difference!","You're unique!","Nice going!","You're inspiring!","Hooray for you!","High five!","You're neat!","Spectacular work!","How extraordinary!","That's incredible!","Great effort!","Way to go!","You're very talented!","I love it!","Brilliant!","Keep it up!","You rule!","Alright!"],n={10:"Wow, you've done a lot of grading!",20:"Jeez, don't you ever stop? You're a machine!",30:"Whoa, leave some grading for the others... Nah, keep going!",40:"We're going to run out of submissions if you keep going! (But please do!)",50:"Fifty!? Am I reading this right?",60:"Wait, are you really reading these?! That's incredible!",70:"Hey, that's gotta be a record!",80:"I'm starting to lose count... Beautiful!"};return n[e]===void 0?t[Math.floor(Math.random()*t.length)]:n[e]},next:function(n,i,a,o){var r=this;this.fetchPeerGradingSet(i,a).done(function(){var s,l=r.peerGradingSet.get("items"),u=!1;if(o||0===l.size())u=!0;else{if(s=l.find(function(e){return!e.evaluation.get("submitTime")}))return e.Routing.redirect({courseId:n.id,assessmentId:i.id,peerGradingSetId:a,peerGradingId:s.id}),void 0;u=!0}u&&(s=r.fetchIndexedPeerGradingAndReturn(l.size())),t.ifOrWhen(!u,s.fetchPromise.pipe(function(){return s.fetchEvaluation()}).done(function(){l.push(s)})).done(function(){e.Routing.redirect({courseId:n.id,assessmentId:i.id,peerGradingSetId:a,peerGradingId:s.id})}).fail(function(e,t,n){c.alertAjaxError("Could not get a new task from the service.  Please try again later.",e,t,n)})}).fail(function(e,t,n){c.alertAjaxError("Could not get a list of tasks from the service.  Please try again later.",e,t,n)})},editAntecedent:function(t,n,i,a){a--,a>=0&&e.Routing.redirect({courseId:t.id,assessmentId:n.id,peerGradingSetId:i,peerGradingId:a})},editSubsequent:function(t,n,i,a){a++,e.Routing.redirect({courseId:t.id,assessmentId:n.id,peerGradingSetId:i,peerGradingId:a})},edit:function(e,n,a,o){var r,l=this,u=null;this.modelizePeerGradingSet(e,n,a),t.ifOrWhen(!this.peerGradingSet||!this.peerGradingSet.fetchPromise,this.peerGradingSet&&this.peerGradingSet.fetchPromise.done(function(){r=l.peerGradingSet.get("items").find(function(e){return e.id===parseInt(o,10)})})).always(function(){if(r===void 0){r=i.extend(new s({id:o}),{peerGradingSet:l.peerGradingSet});var a=r.fetch();u=a.pipe(function(){return r.fetchEvaluation()}),l.peerGradingSet&&l.peerGradingSet.get("items").add(r,{at:o-1})}else r.evaluation||(u=r.fetchEvaluation());t.ifOrWhen(null===u,u).done(function(){l.showPeerGradingEditView(e,n,l.peerGradingSet,r,r.evaluation,r.evaluation.submission)}).fail(function(e,t,n){c.alertAjaxError("Could not get the task from the service.  Please try again later.",e,t,n)})})},fetchPeerGradingSet:function(t,a){var o=this;return this.peerGradingSet&&null!==this.peerGradingSet.fetchPromise?this.peerGradingSet.fetchPromise:(this.peerGradingSet||(this.peerGradingSet=i.extend(new r({id:a}),{assessment:t})),this.peerGradingSet.fetchPromise=this.peerGradingSet.fetch().pipe(function(){return n.when.apply(null,o.peerGradingSet.get("items").reduce(function(e,t){return e.push(t.fetchEvaluation()),e},[]))}).fail(function(){e.logEvent("system.fatal","Could not get peerGradingSet "+a)}))},fetchPeerGradings:function(e,t){return this.fetchPeerGradingSet(e,t)},fetchIndexedPeerGradingAndReturn:function(e){var t=this,n=i.extend(new s({id:e}),{peerGradingSet:t.peerGradingSet});return n.fetchPromise=n.fetch(),n}};return d});
define('models/SelfGrading',["app/Assess","lib/Util","jquery","underscore","backbone","marionette","models/Evaluation"],function(e,t,n,i,a,o,r){var s=a.Model.extend({selfGradingSet:null,evaluation:null,fetchPromise:null,getBaseUrl:function(){return this.selfGradingSet?this.selfGradingSet.getBaseUrl():""},url:function(){return e.assert(this.selfGradingSet,"this.selfGradingSet undefined on selfGradingSet "+this.id),this.isNew()?this.selfGradingSet.url()+"/selfGradings":this.selfGradingSet.url()+"/selfGradings/"+this.id},fetchEvaluation:function(){var e=this;return this.fetchPromise||this.fetch(),this.fetchPromise.pipe(function(){var n=null;return e.evaluation||(e.evaluation=new r({id:e.get("evaluationId")}),n=e.evaluation.fetch()),t.ifOrWhen(null===n,n)})}});return s.prototype.fetch=e.DEV_STANDALONE?function(e){e=e?i.clone(e):{};var t=this,o=e.success;return e.success=function(n,i,a){return t.set(t.parse(n,a),e)?(o&&o(t,n),void 0):!1},e.error=a.wrapError(e.error,t,e),e.success.call(void 0,{id:"PEERGRADING_FROM_FETCH",evaluationId:"EVALUATION_FROM_FETCH",required:!0,lastRequired:!0},"success",null),this.fetchPromise=n.Deferred().resolve(null,null,{status:200}).promise()}:function(e){return this.fetchPromise=a.Model.prototype.fetch.call(this,e)},s});
define('models/SelfGradingSet',["app/Assess","jquery","underscore","backbone","marionette","models/SelfGrading"],function(e,t,n,i,a,o){var r=i.Collection.extend({model:o}),s=i.Model.extend({assessment:null,initialize:function(){var e=this,t=new r;this.set("items",t),t.on("reset",function(){t.each(function(t){t.selfGradingSet=e})}),t.on("add",function(t){t.selfGradingSet=e})},getBaseUrl:function(){return this.assessment?this.assessment.getBaseUrl():""},url:function(){return this.isNew()?(e.assert(this.assessment,"this.assessment undefined on selfGradingSet "+this.id),this.assessment.url()+"/selfGradingSets/latest"):this.getBaseUrl()+"selfGradingSets/"+this.id},parse:function(e){return this.get("items").reset(e.items),delete e.items,e}});return e.DEV_STANDALONE&&(s.prototype.fetch=function(e){e=e?n.clone(e):{};var a=this,o=e.success;return e.success=function(t,n,i){return a.set(a.parse(t,i),e)?(o&&o(a,t),void 0):!1},e.error=i.wrapError(e.error,a,e),e.success.call(void 0,{id:"SELFGRADINGSET_FROM_FETCHLIST",items:[{id:"SELFGRADING_FROM_FETCHLIST",evaluationId:"EVALUATION_FROM_FETCHLIST",required:!0,lastRequired:!1},{id:"SELFGRADING_FROM_FETCHLIST2",evaluationId:"EVALUATION_FROM_FETCHLIST",required:!0,lastRequired:!0},{id:"SELFGRADING_FROM_FETCHLIST3",evaluationId:"EVALUATION_FROM_FETCHLIST",required:!1,lastRequired:!1}],status:"pass"},"success",null),t.Deferred().resolve(null,null,{status:200}).promise()}),s});
define('templates/SelfGradingSetView.hbs',[],function(){return function(e,t,n,i,a){function o(){return"\n        Overall Grade\n        "}function r(){return"\n        Progress\n        "}function s(e,t,i){var a,o,r,s,l="";return l+="\n    <tr>\n      <td>",s=n.index,s?a=s.call(e,{hash:{}}):(a=e.index,a=typeof a===d?a():a),l+=p(a)+'</td>\n      <td><a href="',a=i.selfGradingSet,a=null==a||a===!1?a:a.id,s=n.selfGradingSetPath,a=s?s.call(e,a,{hash:{}}):h.call(e,"selfGradingSetPath",a,{hash:{}}),l+=p(a)+"/selfGradings/",s=n.id,s?a=s.call(e,{hash:{}}):(a=e.id,a=typeof a===d?a():a),l+=p(a)+'" class="hg-internal">',a=e.evaluation,o={},r=i.assessmentModel,o.assessment=r,s=n.studentGradingProgress,a=s?s.call(e,a,{hash:o}):h.call(e,"studentGradingProgress",a,{hash:o}),(a||0===a)&&(l+=a),l+="</a></td>\n    </tr>"}n=n||e.helpers;var l,u,c="",d="function",p=this.escapeExpression,h=n.helperMissing,f=this;return c+='\n<h1 class="pageTitle">Evaluate your own assessment work</h1>\n<table id="selfGradingSet" class="setView table table-striped">\n  <thead>\n    <tr>\n      <th>Number</th>\n      <th>\n        ',l=t.displayGrade,l=n["if"].call(t,l,{hash:{},inverse:f.program(3,r,a),fn:f.program(1,o,a)}),(l||0===l)&&(c+=l),c+="\n      </th>\n    </tr>\n  </thead>\n  <tbody>",l=t.selfGradings,u=n.eachWithIndex,l=u?u.call(t,l,{hash:{},inverse:f.noop,fn:f.programWithDepth(s,a,t)}):h.call(t,"eachWithIndex",l,{hash:{},inverse:f.noop,fn:f.programWithDepth(s,a,t)}),(l||0===l)&&(c+=l),c+='\n  </tbody>\n</table>\n<div id="bottomContentToolbar" class="contentToolbar form-actions hide"></div>'}});
define('views/SelfGradingSetView',["app/Assess","jquery","underscore","backbone","marionette","modelbinding","handlebars","models/SelfGradingSet","views/BaseView","templates/SelfGradingSetView.hbs"],function(e,t,n,i,a,o,r,s,l,u){var c=l.extend({template:function(){return r.template(u)},initialize:function(){var t=this;r.registerHelper("selfGradingSetPath",function(n){return e.BACKBONE_ROOT+"courses/"+t.model.get("assessmentModel").course.id+"/assessments/"+t.model.get("assessmentModel").id+"/selfGradingSets/"+n})},onShow:function(){this.$el.hide().fadeIn()}});return c});
define('templates/SelfGradingSubmitSuccess.hbs',[],function(){return function(e,t,n){n=n||e.helpers;var i,a,o="",r="function",s=this.escapeExpression;return o+='\n<p>\n   \n  Your work was submitted.<a href="',a=n.buttonLink,a?i=a.call(t,{hash:{}}):(i=t.buttonLink,i=typeof i===r?i():i),o+=s(i)+'" role="button" class="hg-internal btn btn-primary">',a=n.buttonText,a?i=a.call(t,{hash:{}}):(i=t.buttonText,i=typeof i===r?i():i),o+=s(i)+"</a>\n</p>"}});
define('views/SelfGradingEditView',["app/Assess","jquery","underscore","backbone","marionette","modelbinding","models/Evaluation","views/SubmissionBaseView","handlebars","templates/SelfGradingSubmitSuccess.hbs"],function(e,t,n,i,a,o,r,s){var l=s.extend({events:function(){return n.extend({},s.prototype.events,{"click #assessmentSave":"save","click #assessmentSubmit":"submit"})},render:function(){var e=this.model.get("assessmentModel");this.renderVariant({step:"selfGrading",submissionAuthor:"you",shrinkLargeInstructions:!0,editableEvaluation:e.access.isStepWritable("selfGrading")})},saveToServer:function(){return this.syncRichTextEditors(),this.blurAllInputs(),this.model.get("evaluationModel").save()},save:function(t){var i=this;t.preventDefault();var a=this.saveToServer(t);a?a.done(function(){i.hideAllFieldErrors(),e.app.vent.trigger("assessmentAlert",{type:"success",html:'Your draft was saved but <span class="hg-warning-text"><b><i>not</i></b> yet submitted</span>.'})}).fail(n.bind(i.handleApiErrors,i)):e.log("Backbone validation failed during save.",this)},submit:function(i){var a=this;i.preventDefault();var o=this.saveToServer(i);o?o.done(function(){a.hideAllFieldErrors();var i=a.model.get("selfGradingModel");t.post(i.url()+"/submit").pipe(null,function(n){return e.DEV_STANDALONE?t.Deferred().resolve().promise():n.promise()}).pipe(function(){return i.evaluation.fetch()}).done(function(){a.hideAllFieldErrors(),t("#submissionToolbar").stop(!0,!0).fadeOut({duration:300,queue:!1}).slideUp(300),a.trigger("showActionBar"),e.app.vent.trigger("assessmentAlert",{type:"success",html:"Your work was submitted."})}).fail(n.bind(a.handleApiErrors,a))}).fail(n.bind(a.handleApiErrors,a)):e.log("Backbone validation failed during submit.",this)}});return l});
define('controllers/SelfGradingSetsController',["app/Assess","lib/Util","jquery","underscore","backbone","marionette","models/SelfGradingSet","models/SelfGrading","views/SelfGradingSetView","views/SelfGradingEditView","views/ViewHelpers"],function(e,t,n,i,a,o,r,s,l,u,c){var d={parentLayout:null,selfGradingSet:null,modelize:function(){var e=Array.prototype.slice.call(arguments),t=e.shift(),n=e.shift(),a=e.shift();return this.selfGradingSet||(this.selfGradingSet=i.extend(new r({id:a}),{assessment:n})),[t,n,this.selfGradingSet].concat(e)},modelizeSelfGradingSet:function(e,t,n){this.selfGradingSet||(this.selfGradingSet=this.modelize(e,t,n)[2])},showView:function(e){this.parentLayout.contentRegion.show(e)},showSelfGradingEditView:function(t,n,i,a,o,r){var s=this;n.fetchPromise.done(function(){var l=new u(e.wrappedViewModel({assessment:n.attributes,selfGrading:a.attributes,evaluation:o.attributes,submission:r.attributes,assessmentModel:n,selfGradingModel:a,evaluationModel:o,submissionModel:r}));l.on("showActionBar",function(){s.updateSelfGradingSet(t,n,i).always(function(){s.showActionBar({toolbars:["topContentToolbar","bottomContentToolbar"]},t,n,i)})}),s.showView(l)})},showSelfGradingSetView:function(t,n){var i=this;t.fetchPromise.done(function(){var a=new l(e.wrappedViewModel({displayGrade:t.isDisplayGradeEnabled(),selfGradingSet:n.attributes,selfGradings:n.get("items"),assessmentModel:t}));i.showView(a)})},index:function(t,n,i){var a=this;this.updateSelfGradingSet(t,n,i).always(function(){e.Routing.redirect({courseId:t.id,assessmentId:n.id,selfGradingSetId:a.selfGradingSet.id,selfGradingId:0})})},updateSelfGradingSet:function(e,n,i){var a=this;return this.fetchSelfGradingSet(n,i).pipe(function(){var e,n=a.selfGradingSet.get("items"),i=!1;return 0===n.size()?i=!0:(e=n.at(n.size()-1),e.evaluation.get("submitTime")&&e.get("required")&&!e.get("lastRequired")&&(i=!0)),i&&(e=a.fetchIndexedSelfGradingAndReturn(n.size())),t.ifOrWhen(!i,e.fetchPromise.pipe(function(){return e.fetchEvaluation()}).done(function(){n.push(e)})).fail(function(e,t,n){c.alertAjaxError("Could not get a new task from the service.  Please try again later.",e,t,n)})}).fail(function(e,t,n){c.alertAjaxError("Could not get a list of tasks from the service.  Please try again later.",e,t,n)})},showActionBar:function(t,n,i){var a="<p>Congratulations on finishing this assignment.  To see your results, come back afer the evaluation deadline has passed.</p>";a+='<div class="contentToolbarButtons pull-right"><a id="assessmentSubmit" href="#" role="button" class="hg-internal btn">Re-submit</a></div>',a+='<p>In the meantime, you can go back and evaluate more of your classmates\' work: <a class="hg-internal" href="'+e.Routing.redirectPath({courseId:n.id,assessmentId:i.id,peerGradingSetId:null})+'"><i class="icon-arrow-left"></i> Return to peer-evaluation</a></p>',a&&e.app.vent.trigger("updateContentToolbars",{toolbars:t.toolbars,html:a})},edit:function(e,n,a,o){var r,l=this,u=null;t.ifOrWhen(!this.selfGradingSet||!this.selfGradingSet.fetchPromise,this.selfGradingSet&&this.selfGradingSet.fetchPromise.done(function(){r=l.selfGradingSet.get("items").find(function(e){return e.id===parseInt(o,10)})})).always(function(){r===void 0&&(l.modelizeSelfGradingSet(e,n,a),r=i.extend(new s({id:o}),{selfGradingSet:l.selfGradingSet}),u=r.fetch()),t.ifOrWhen(null===u,u&&u.pipe(function(){return r.fetchEvaluation()})).done(function(){l.showSelfGradingEditView(e,n,a,r,r.evaluation,r.evaluation.submission)}).fail(function(e,t,n){c.alertAjaxError("Could not get the task from the service.  Please try again later.",e,t,n)})})},fetchSelfGradingSet:function(t,n){var a=this;return this.selfGradingSet&&null!==this.selfGradingSet.fetchPromise?this.selfGradingSet.fetchPromise:(this.selfGradingSet=i.extend(new r({id:n}),{assessment:t}),this.selfGradingSet.fetchPromise=this.selfGradingSet.fetch().pipe(function(){return a.selfGradingSet.get("items").reduce(function(e,t){return null===e?t.fetchEvaluation():e.pipe(function(){return t.fetchEvaluation()})},null)}).fail(function(){e.logEvent("system.fatal","Could not get selfGradingSet "+n)}))},fetchIndexedSelfGradingAndReturn:function(e){var t=this,n=i.extend(new s({id:e}),{selfGradingSet:t.selfGradingSet});return n.fetchPromise=n.fetch(),n}};return d});
define('views/ResultShowView',["app/Assess","jquery","underscore","backbone","marionette","modelbinding","views/SubmissionBaseView"],function(e,t,n,i,a,o,r){var s=r.extend({render:function(){this.renderVariant({step:"results",shrinkLargeInstructions:!0})}});return s});
define('controllers/ResultsController',["app/Assess","jquery","underscore","backbone","marionette","models/Submission","models/OverallEvaluation","views/ResultShowView","views/ViewHelpers"],function(e,t,n,i,a,o,r,s,l){var u={parentLayout:null,showView:function(e){this.parentLayout.contentRegion.show(e)},showResultShowView:function(n,i,a){var o=this;t.when(n.fetchPromise,i.fetchPromise,a.fetchPromise).done(function(){o.showView(new s(e.wrappedViewModel({assessment:n.attributes,submission:i.attributes,overallEvaluation:a.attributes,assessmentModel:n,submissionModel:i,overallEvaluationModel:a})))})},index:function(t,n){e.Routing.redirect({courseId:t.id,assessmentId:n.id,resultId:"mine"})},showMine:function(i,a){var s,u,c=this;t.getJSON(e.API_BASE_URL+"assessments/"+a.get("id")+"/submissions").fail(function(e,t,n){l.alertAjaxError("Could not get your submission from the service.",e,t,n)}).done(function(t){if(t)if(t.length){var i=t[t.length-1];s=n.extend(new o(i),{assessment:a}),s.fetchPromise=s.fetch().fail(function(e,t,n){l.alertAjaxError("Could not get your submission from the service.",e,t,n)}),u=n.extend(new r,{submission:s}),u.fetchPromise=u.fetch().fail(function(e,t,n){l.alertAjaxError("Could not get your submission's overall evaluation from the service.",e,t,n)}),c.showResultShowView(a,s,u)}else l.alertAjaxError("Could not find your submission. Are you sure you submitted one?");else e.logEvent("system.fatal","submissionsJson is not defined.")})}};return u});
define('models/Calibration',["app/Assess","lib/Util","jquery","underscore","backbone","marionette","models/Evaluation"],function(e,t,n,i,a,o,r){var s=a.Model.extend({calibrationSet:null,evaluation:null,fetchPromise:null,getBaseUrl:function(){return this.calibrationSet?this.calibrationSet.getBaseUrl():""},url:function(){return e.assert(this.calibrationSet,"this.calibrationSet undefined on calibrationSet "+this.id),this.isNew()?this.calibrationSet.url()+"/calibrationGradings":this.calibrationSet.url()+"/calibrationGradings/"+this.id},fetchEvaluation:function(){var e=this;return e.evaluation||(e.evaluation=new r({id:e.get("evaluationId")}),e.fetchPromise=e.evaluation.fetch()),t.ifOrWhen(null===e.fetchPromise,e.fetchPromise)},selectedAttributeIfTypeIs:function(e){return this.get("type")==e?'selected="selected"':""}});return s.prototype.fetch=function(e){return this.fetchPromise=a.Model.prototype.fetch.call(this,e)},s});
define('models/CalibrationSet',["app/Assess","jquery","underscore","backbone","marionette","models/Calibration"],function(e,t,n,i,a,o){var r=i.Collection.extend({model:o}),s=i.Model.extend({assessment:null,initialize:function(){var e=this,t=new r;this.set("items",t),t.on("reset",function(){t.each(function(t){t.calibrationSet=e})}),t.on("add",function(t){t.calibrationSet=e})},getBaseUrl:function(){return this.assessment?this.assessment.getBaseUrl():""},url:function(){return this.isNew()?(e.assert(this.assessment,"this.assessment undefined on calibrationSet "+this.id),this.assessment.url()+"/calibrationSets/latest"):this.getBaseUrl()+"calibrationSets/"+this.id},parse:function(e){return this.get("items").reset(e.items),delete e.items,e}});return e.DEV_STANDALONE&&(s.prototype.fetch=function(e){e=e?n.clone(e):{};var a=this,o=e.success;return e.success=function(t,n,i){return a.set(a.parse(t,i),e)?(o&&o(a,t),void 0):!1},e.error=i.wrapError(e.error,a,e),e.success.call(void 0,{id:"CALIBRATIONSET_FROM_FETCHLIST",items:[{id:"CALIBRATION_FROM_FETCHLIST",evaluationId:"EVALUATION_FROM_FETCHLIST",required:!0,lastRequired:!1},{id:"CALIBRATION_FROM_FETCHLIST2",evaluationId:"EVALUATION_FROM_FETCHLIST",required:!0,lastRequired:!0},{id:"CALIBRATION_FROM_FETCHLIST3",evaluationId:"EVALUATION_FROM_FETCHLIST",required:!1,lastRequired:!1}],status:"pass"},"success",null),t.Deferred().resolve(null,null,{status:200}).promise()}),s});
define('templates/CalibrationSetView.hbs',[],function(){return function(e,t,n,i,a){function o(e,t,i){var a,o,l,u,c="";return c+='\n    <tr>\n      <td><a href="',a=i.calibrationSet,a=null==a||a===!1?a:a.id,u=n.calibrationSetPath,a=u?u.call(e,a,{hash:{}}):d.call(e,"calibrationSetPath",a,{hash:{}}),c+=p(a)+"/calibrationGradings/",u=n.id,u?a=u.call(e,{hash:{}}):(a=e.id,a=typeof a===h?a():a),c+=p(a)+'" class="hg-internal">',a=e.evaluation,a=null==a||a===!1?a:a.submission,u=n.author,a=u?u.call(e,a,{hash:{}}):d.call(e,"author",a,{hash:{}}),c+=p(a)+"</a></td>\n      <td>\n        ",a=e.evaluation,a=null==a||a===!1?a:a.submission,a=null==a||a===!1?a:a.attributes,a=n["with"].call(e,a,{hash:{},inverse:f.noop,fn:f.program(2,r,t)}),(a||0===a)&&(c+=a),c+="\n      </td>\n      <td>",a=e.evaluation,u=n.staffGradingProgress,a=u?u.call(e,a,{hash:{}}):d.call(e,"staffGradingProgress",a,{hash:{}}),(a||0===a)&&(c+=a),c+="</td>\n      <td>\n        ",a=e.evaluation,a=null==a||a===!1?a:a.attributes,a=n["with"].call(e,a,{hash:{},inverse:f.noop,fn:f.program(4,s,t)}),(a||0===a)&&(c+=a),c+="\n      </td>\n      <td>",a=e.evaluation,o={},l=i.assessmentModel,o.assessment=l,u=n.earmarkOptions,a=u?u.call(e,a,{hash:o}):d.call(e,"earmarkOptions",a,{hash:o}),(a||0===a)&&(c+=a),c+="</td>\n    </tr>"}function r(e){var t,i,a="";return a+="\n        ",t=e.submitTime,i=n.fromTimeStringToLocaleString,t=i?i.call(e,t,{hash:{}}):d.call(e,"fromTimeStringToLocaleString",t,{hash:{}}),a+=p(t)+"\n        "}function s(e){var t,i,a="";return a+="\n        ",t=e.submitTime,i=n.fromTimeStringToLocaleString,t=i?i.call(e,t,{hash:{}}):d.call(e,"fromTimeStringToLocaleString",t,{hash:{}}),a+=p(t)+"\n        "}n=n||e.helpers;var l,u,c="",d=n.helperMissing,p=this.escapeExpression,h="function",f=this;return c+='\n<h1 class="pageTitle">Grade submissions, earmark them for special treatment</h1>\n<table id="calibrationSet" class="setView table table-striped">\n  <thead>\n    <tr>\n      <th style="width:30%">Name</th>\n      <th>Submission Date</th>\n      <th>Staff Grade</th>\n      <th>Staff Grading Date</th>\n      <th>Earmarked for</th>\n    </tr>\n  </thead>\n  <tbody>\n    <!-- TODO No need for eachWithIndex anymore-->',l=t.calibrations,u=n.eachWithIndex,l=u?u.call(t,l,{hash:{},inverse:f.noop,fn:f.programWithDepth(o,a,t)}):d.call(t,"eachWithIndex",l,{hash:{},inverse:f.noop,fn:f.programWithDepth(o,a,t)}),(l||0===l)&&(c+=l),c+='\n  </tbody>\n</table>\n<div id="bottomContentToolbar" class="contentToolbar form-actions hide"></div>'}});
define('views/CalibrationSetView',["app/Assess","lib/Util","jquery","underscore","backbone","marionette","modelbinding","handlebars","views/BaseView","models/CalibrationSet","models/Calibration","templates/CalibrationSetView.hbs"],function(e,t,n,i,a,o,r,s,l,u,c,d){s.registerHelper("staffGradingProgress",function(e){return e.get("submitTime")?e.get("grade")!==void 0?t.round(e.get("grade"),1):"-":"?"}),s.registerHelper("earmarkOptions",function(e,t){if(!e.get("submitTime"))return"-";var n=this.selectedAttributeIfTypeIs("groundTruth"),i='<select class="calibrationTypeMenu" name="calibrationType['+this.id+']">';return t.hash.assessment.isStepEnabled("training")?i+='<option value="training" '+this.selectedAttributeIfTypeIs("training")+">training</option>":""!==this.selectedAttributeIfTypeIs("training")&&(n=this.selectedAttributeIfTypeIs("training")),i+='<option value="groundTruth" '+n+">ground truth</option>",i+='<option value="staffGradeOnly" '+this.selectedAttributeIfTypeIs("staffGradeOnly")+">staff-grade only</option>",i+="</select>"});var p=l.extend({template:function(){return s.template(d)},events:{"change .calibrationTypeMenu":"changeCalibrationType"},initialize:function(){var t=this;s.registerHelper("calibrationSetPath",function(n){return e.BACKBONE_ROOT+"courses/"+t.model.get("assessmentModel").course.id+"/assessments/"+t.model.get("assessmentModel").id+"/calibrationSets/"+n})},onShow:function(){this.$el.hide().fadeIn()},changeCalibrationType:function(e){var t=n(e.currentTarget);e.preventDefault();var i=t.attr("name").replace(/^calibrationType\[(\d+)\]$/,"$1");if(i){var a=this.model.get("calibrations").get(i);a&&(a.set("type",t.val()),a.save())}}});return p});
define('templates/CalibrationSubmitSuccess.hbs',[],function(){return function(e,t,n){n=n||e.helpers;var i,a,o="",r="function",s=this.escapeExpression;return o+='\n<p>\n   \n  Your work was submitted.<a href="',a=n.buttonLink,a?i=a.call(t,{hash:{}}):(i=t.buttonLink,i=typeof i===r?i():i),o+=s(i)+'" role="button" class="hg-internal btn btn-primary">',a=n.buttonText,a?i=a.call(t,{hash:{}}):(i=t.buttonText,i=typeof i===r?i():i),o+=s(i)+"</a>\n</p>"}});
define('views/CalibrationEditView',["app/Assess","jquery","underscore","backbone","marionette","modelbinding","models/Evaluation","views/SubmissionBaseView","handlebars","templates/CalibrationSubmitSuccess.hbs"],function(e,t,n,i,a,o,r,s){var l=s.extend({events:function(){return n.extend({},s.prototype.events,{"click #assessmentSkip":"skip","click #assessmentSave":"save","click #assessmentSubmit":"submit"})},render:function(){this.renderVariant({step:"calibration",submissionAuthor:this.model.get("submissionModel").get("authorName"),shrinkLargeInstructions:!0,editableEvaluation:!0,skippableEvaluation:!0})},skip:function(t){var n=this;t.preventDefault(),e.Routing.redirect({courseId:n.model.get("assessmentModel").course.id,assessmentId:n.model.get("assessmentModel").id,calibrationSetId:n.model.get("calibrationModel").calibrationSet.id},"/fetchNew")},saveToServer:function(){return this.syncRichTextEditors(),this.blurAllInputs(),this.model.get("evaluationModel").save()},save:function(t){var i=this;t.preventDefault();var a=this.saveToServer(t);a?a.done(function(){e.app.vent.trigger("assessmentAlert",{type:"success",html:'Your draft was saved but <span class="hg-warning-text"><b><i>not</i></b> yet submitted</span>.'})}).fail(n.bind(i.handleApiErrors,i)):e.log("Backbone validation failed during save.",this)},submit:function(i){var a=this;i.preventDefault();var o=this.saveToServer(i);o?o.done(function(){var i=a.model.get("calibrationModel");t.post(i.url()+"/submit").pipe(function(e){return i.set(e),i.evaluation.fetch()}).done(function(){t("#submissionToolbar").stop(!0,!0).fadeOut({duration:300,queue:!1}).slideUp(300),a.trigger("showActionBar"),e.app.vent.trigger("assessmentAlert",{type:"success",html:"Your work was submitted."})}).fail(n.bind(a.handleApiErrors,a))}).fail(n.bind(a.handleApiErrors,a)):e.log("Backbone validation failed during submit.",this)}});return l});
define('controllers/CalibrationSetsController',["app/Assess","lib/Util","jquery","underscore","backbone","marionette","models/CalibrationSet","models/Calibration","views/CalibrationSetView","views/CalibrationEditView","views/ViewHelpers"],function(e,t,n,i,a,o,r,s,l,u,c){var d={parentLayout:null,calibrationSet:null,modelize:function(){var e=Array.prototype.slice.call(arguments),t=e.shift(),n=e.shift(),a=e.shift();return this.calibrationSet||(this.calibrationSet=i.extend(new r({id:a}),{assessment:n}),this.calibrationSet.fetchPromise=this.calibrationSet.fetch()),[t,n,this.calibrationSet].concat(e)},modelizeCalibrationSet:function(e,t,n){this.calibrationSet||(this.calibrationSet=this.modelize(e,t,n)[2])},showView:function(e){this.parentLayout.contentRegion.show(e)},showCalibrationEditView:function(t,n,i,a,o,r){var s=this;n.fetchPromise.done(function(){var l=new u(e.wrappedViewModel({returnUrl:e.Routing.redirectPath({courseId:t.id,assessmentId:n.id,calibrationSetId:i}),assessment:n.attributes,calibration:a.attributes,evaluation:o.attributes,submission:r.attributes,assessmentModel:n,calibrationModel:a,evaluationModel:o,submissionModel:r}));l.on("showActionBar",function(){s.updateCalibrationSet(t,n,i).always(function(){s.showActionBar({toolbars:["topContentToolbar","bottomContentToolbar"]},t,n,i)})}),s.showView(l)})},showCalibrationSetView:function(t,n){var i=this;t.fetchPromise.done(function(){var a=new l(e.wrappedViewModel({displayGrade:t.isDisplayGradeEnabled(),calibrationSet:n.attributes,calibrations:n.get("items"),assessment:t.attributes,assessmentModel:t}));i.showView(a)})},index:function(e,t,n){var i=this;this.updateCalibrationSet(e,t,n).always(function(){i.showCalibrationSetView(t,i.calibrationSet),i.showActionBar({toolbars:"bottomContentToolbar"},e,t,n)})},updateCalibrationSet:function(e,n,i){var a=this;return this.fetchCalibrationSet(n,i).pipe(function(){var e,n=a.calibrationSet.get("items"),i=!1;return 0===n.size()?i=!0:(e=n.at(n.size()-1),e.evaluation.get("submitTime")&&(i=!0)),i&&(e=a.fetchIndexedCalibrationAndReturn(n.size())),t.ifOrWhen(!i,e.fetchPromise.pipe(function(){return e.fetchEvaluation()}).done(function(){n.push(e)})).fail(function(e,t,n){c.alertAjaxError("Could not get a new task from the service.  Please try again later.",e,t,n)})}).fail(function(e,t,n){c.alertAjaxError("Could not get a list of tasks from the service.  Please try again later.",e,t,n)})},showActionBar:function(t,n,a){var o=this,r=i.isArray(t.toolbars),s="",l=o.calibrationSet.get("items"),u=null;l.size()>0&&(u=l.at(l.size()-1)),r&&(s+='<div class="contentToolbarButtons pull-right"><a id="assessmentSubmit" href="#" role="button" class="hg-internal btn">Re-submit</a>'),u&&(s+='<a class="hg-internal btn btn-primary" href="'+e.Routing.redirectPath({courseId:n.id,assessmentId:a.id,calibrationSetId:o.calibrationSet.id})+'/next">Evaluate next student</a>'),r&&(s+="</div>"),s&&e.app.vent.trigger("updateContentToolbars",{toolbars:t.toolbars,html:s})},next:function(n,i,a,o){var r=this;this.fetchCalibrationSet(i,a).done(function(){var s,l=r.calibrationSet.get("items"),u=!1;o||0===l.size()?u=!0:(s=l.at(l.size()-1),s.evaluation.get("submitTime")&&(u=!0)),u&&(s=r.fetchIndexedCalibrationAndReturn(l.size())),t.ifOrWhen(!u,s.fetchPromise.pipe(function(){return s.fetchEvaluation()}).done(function(){l.push(s)})).done(function(){e.Routing.redirect({courseId:n.id,assessmentId:i.id,calibrationSetId:a,calibrationGradingId:s.id})}).fail(function(e,t,n){c.alertAjaxError("Could not get a new task from the service.  Please try again later.",e,t,n)})}).fail(function(e,t,n){c.alertAjaxError("Could not get a list of tasks from the service.  Please try again later.",e,t,n)})},fetchNew:function(e,t,n){return this.next(e,t,n,!0)},edit:function(e,n,a,o){var r,l=this,u=null;t.ifOrWhen(!this.calibrationSet||!this.calibrationSet.fetchPromise,this.calibrationSet&&this.calibrationSet.fetchPromise.done(function(){r=l.calibrationSet.get("items").find(function(e){return e.id===parseInt(o,10)})})).always(function(){r===void 0&&(l.modelizeCalibrationSet(e,n,a),r=i.extend(new s({id:o}),{calibrationSet:l.calibrationSet}),u=r.fetch()),t.ifOrWhen(null===u,u&&u.pipe(function(){return r.fetchEvaluation()})).done(function(){l.showCalibrationEditView(e,n,a,r,r.evaluation,r.evaluation.submission)}).fail(function(e,t,n){c.alertAjaxError("Could not get the task from the service.  Please try again later.",e,t,n)})})},fetchCalibrationSet:function(t,a){var o=this;return this.calibrationSet&&null!==this.calibrationSet.fetchPromise?this.calibrationSet.fetchPromise:(this.calibrationSet=i.extend(new r({id:a}),{assessment:t}),this.calibrationSet.fetchPromise=this.calibrationSet.fetch().pipe(function(){return n.when.apply(null,o.calibrationSet.get("items").reduce(function(e,t){return e.push(t.fetchEvaluation()),e},[]))}).fail(function(){e.logEvent("system.fatal","Could not get calibrationSet "+a)}))},fetchCalibrations:function(e,t){return this.fetchCalibrationSet(e,t)},fetchIndexedCalibrationAndReturn:function(e){var t=this,n=i.extend(new s({id:e}),{calibrationSet:t.calibrationSet});return n.fetchPromise=n.fetch(),n}};return d});
define('templates/AssessmentAlert.hbs',[],function(){return function(e,t,n){n=n||e.helpers;var i,a,o="",r="function";return o+='\n<div id="assessmentAlert"><a data-dismiss="alert" href="#" class="close">x</a>\n  <p>',a=n.message,a?i=a.call(t,{hash:{}}):(i=t.message,i=typeof i===r?i():i),(i||0===i)&&(o+=i),o+="</p>\n</div>"}});
define('templates/AssessmentActionBar.hbs',[],function(){return function(e,t,n){n=n||e.helpers;var i,a,o="",r="function";return o+='\n<div class="assessmentActionBar">',a=n.html,a?i=a.call(t,{hash:{}}):(i=t.html,i=typeof i===r?i():i),(i||0===i)&&(o+=i),o+="</div>"}});
define('controllers/AssessmentsController',["app/Assess","lib/Util","jquery","underscore","backbone","marionette","bootstrap_alert","views/AssessmentsLayout","views/ViewHelpers","views/AssessmentNavigationView","models/AssessmentNavigationViewModel","models/Course","models/Assessment","models/AssessmentAccess","controllers/SubmissionsController","controllers/TrainingSetsController","controllers/PeerGradingSetsController","controllers/SelfGradingSetsController","controllers/ResultsController","controllers/CalibrationSetsController","handlebars","templates/AssessmentAlert.hbs","templates/AssessmentActionBar.hbs"],function(e,t,n,i,a,o,r,s,l,u,c,d,h,p,f,m,g,v,b,y,w,x,k){var _={assessment:null,assessmentAccess:null,assessmentNavigation:null,assessmentNavigationView:null,modelize:function(){var a=this,o=Array.prototype.slice.call(arguments),r=o.shift(),s=o.shift();return e.Ajax.inizIntercept(n,s),this.assessmentAccess||(this.assessmentAccess=new p({id:s,previewPhase:t.getUrlParam(window.location.href,"preview")}),n(document).ajaxSuccess(function(e,t){a.assessmentAccess.extractAccessFromXhr(t)})),this.assessment||(this.assessment=i.extend(new h({id:s}),{course:r,access:this.assessmentAccess}),this.assessment.fetchPromise=this.assessment.fetch()),[r,this.assessment].concat(o)},retrieveAccessState:function(t,i){var a=[e.API_BASE_URL,"assessments/",t,"/settings"].join(""),o=this;n.getJSON(a,function(e,t,n){o.assessmentAccess.extractAccessFromXhr(n),i&&i()})},show:function(e,t){var n=this;this.modelize(e,t),this.assessment.fetchPromise.done(function(){n.retrieveAccessState(t,function(){n.onShow(e,t)})})},onShow:function(t,n){var i={courseId:t.get("id"),assessmentId:n},a=this.assessmentAccess.getBestStep();switch(a){case"submitting":i.submissionId=null;break;case"training":i.trainingSetId=null;break;case"peerGrading":i.peerGradingSetId=null;break;case"selfGrading":i.selfGradingSetId=null;break;case"results":i.resultId=null;break;case"calibrate":i.calibrationSetId=null;break;default:i=null,e.logEvent("system.fatal","Failed to determine what step to land on!")}null!==i&&e.Routing.redirect(i)},onNavigation:function(t,i,o){var r=this;if(n("#assessmentMessages").children(".alert").slideUp("slow"),window._gaq){var s=e.BACKBONE_BASE_URL+a.history.getFragment();window._gaq.push(["_trackPageview",s])}e.logEvent("pageview",{fragment:a.history.getFragment()}),r.layout.navigationRegion&&r.retrieveAccessState(o,function(){r.assessment.fetchPromise.done(function(){r.assessmentNavigation||(r.assessmentNavigation=new c({assessment:r.assessment,assessmentAccess:r.assessmentAccess}),r.assessmentNavigationView=new u({model:r.assessmentNavigation}),r.layout.navigationRegion.show(r.assessmentNavigationView)),r.assessmentNavigation.set("assessment",r.assessment),r.assessmentNavigationView.navigateToStep(t)})})}};return i.bindAll(_,"onNavigation"),e.app.vent.on("router:initialized",function(e){e.bind("all",function(){var t=Array.prototype.slice.call(arguments);t.shift(),t.unshift(e.step),_.onNavigation.apply(_,t)})}),e.app.vent.on("assessmentAlert",function(t){var i="alert in fade",a=function(e){e.stop(!0,!0).fadeOut({duration:300,queue:!1}).slideUp(300)},o=n("#assessmentMessages"),r=o.children(".alert");if(!t)return a(r),void 0;switch(t.type){case"warning":break;case"info":case"success":case"error":i+=" alert-"+t.type;break;default:return e.log("Error: Unrecognized alert type",t),void 0}var s=w.template(x)({message:t.html}),l=n(s).attr("class",i);r.length&&a(r),o.append(l).alert(),e.scrollToTop(),t.stayVisible||"info"!=t.type&&"success"!=t.type||window.setTimeout(function(){a(l)},1e4)}),a.history.on("route",function(){n("#assessmentAlert").stop(!0,!0).fadeOut({duration:300,queue:!1}).slideUp(300),n(".tooltip").remove()}),e.app.vent.on("updateContentToolbars",function(t){var a=w.template(k)({html:t.html}),o=!t.toolbars&&["bottomContentToolbar"]||i.isArray(t.toolbars)&&t.toolbars||[t.toolbars];i.each(o,function(e){n("#"+e).empty().append(a).show()}),n("#honorCode")&&n("#assessmentSubmit")&&(n(".assessmentSubmit").click(function(){return n(".honorCode").is(":checked")?void 0:!1}),n(".honorCode").change(function(){n(this).is(":checked")?(n(".assessmentSubmit").removeAttr("disabled","").removeClass("disabled").addClass("btn-primary"),n(".honorCode").prop("checked",!0)):(n(".assessmentSubmit").attr("disabled","disabled").addClass("disabled").removeClass("btn-primary"),n(".honorCode").prop("checked",!1))})),e.scrollToTop()}),e.app.addInitializer(function(){_.layout=new s,_.layout.on("show",function(){e.app.vent.trigger("layout:rendered")}),f.parentLayout=_.layout,m.parentLayout=_.layout,g.parentLayout=_.layout,v.parentLayout=_.layout,b.parentLayout=_.layout,y.parentLayout=_.layout,e.app.mainRegion.show(_.layout)}),_});
define('routers/AssessmentsRouting',["app/Assess","backbone","routers/CoursesRouting","controllers/AssessmentsController"],function(e,t,n,i){var a={};return a.Router=e.Router.extend({appRoutes:{"courses/:courseId/assessments/:assessmentId":"show"}}),a.router=new a.Router({controller:i,parentRouter:n.router}),a});
define('routers/SubmissionsRouting',["app/Assess","backbone","routers/AssessmentsRouting","controllers/SubmissionsController"],function(e,t,n,i){var a={};return a.Router=e.Router.extend({appRoutes:{"courses/:courseId/assessments/:assessmentId/submissions":"index","courses/:courseId/assessments/:assessmentId/submissions/share":"share","courses/:courseId/assessments/:assessmentId/submissions/:submissionId":"show","courses/:courseId/assessments/:assessmentId/submissions/:submissionId/edit":"edit"},step:"submitting"}),a.router=new a.Router({controller:i,parentRouter:n.router}),e.app.vent.trigger("router:initialized",a.router),a});
define('routers/TrainingSetsRouting',["app/Assess","backbone","routers/AssessmentsRouting","controllers/TrainingSetsController"],function(e,t,n,i){var a={};return a.Router=e.Router.extend({appRoutes:{"courses/:courseId/assessments/:assessmentId/trainingSets":"index","courses/:courseId/assessments/:assessmentId/trainingSets/:trainingSetId":"index","courses/:courseId/assessments/:assessmentId/trainingSets/:trainingSetId/next":"next","courses/:courseId/assessments/:assessmentId/trainingSets/:trainingSetId/trainings/:trainingId":"edit"},step:"training"}),a.router=new a.Router({controller:i,parentRouter:n.router}),e.app.vent.trigger("router:initialized",a.router),a});
define('routers/PeerGradingSetsRouting',["app/Assess","backbone","routers/AssessmentsRouting","controllers/PeerGradingSetsController"],function(e,t,n,i){var a={};return a.Router=e.Router.extend({appRoutes:{"courses/:courseId/assessments/:assessmentId/peerGradingSets":"index","courses/:courseId/assessments/:assessmentId/peerGradingSets/:peerGradingSetId":"index","courses/:courseId/assessments/:assessmentId/peerGradingSets/:peerGradingSetId/next":"next","courses/:courseId/assessments/:assessmentId/peerGradingSets/:peerGradingSetId/peerGradings/:peerGradingId":"edit","courses/:courseId/assessments/:assessmentId/peerGradingSets/:peerGradingSetId/peerGradings/:peerGradingId/antecedent":"editAntecedent","courses/:courseId/assessments/:assessmentId/peerGradingSets/:peerGradingSetId/peerGradings/:peerGradingId/subsequent":"editSubsequent"},step:"peerGrading"}),a.router=new a.Router({controller:i,parentRouter:n.router}),e.app.vent.trigger("router:initialized",a.router),a});
define('routers/SelfGradingSetsRouting',["app/Assess","backbone","routers/AssessmentsRouting","controllers/SelfGradingSetsController"],function(e,t,n,i){var a={};return a.Router=e.Router.extend({appRoutes:{"courses/:courseId/assessments/:assessmentId/selfGradingSets":"index","courses/:courseId/assessments/:assessmentId/selfGradingSets/:selfGradingSetId":"index","courses/:courseId/assessments/:assessmentId/selfGradingSets/:selfGradingSetId/selfGradings/:selfGradingId":"edit"},step:"selfGrading"}),a.router=new a.Router({controller:i,parentRouter:n.router}),e.app.vent.trigger("router:initialized",a.router),a});
define('routers/CalibrationSetsRouting',["app/Assess","backbone","routers/AssessmentsRouting","controllers/CalibrationSetsController"],function(e,t,n,i){var a={};return a.Router=e.Router.extend({appRoutes:{"courses/:courseId/assessments/:assessmentId/calibrationSets":"index","courses/:courseId/assessments/:assessmentId/calibrationSets/:calibrationSetId":"index","courses/:courseId/assessments/:assessmentId/calibrationSets/:calibrationSetId/next":"next","courses/:courseId/assessments/:assessmentId/calibrationSets/:calibrationSetId/fetchNew":"fetchNew","courses/:courseId/assessments/:assessmentId/calibrationSets/:calibrationSetId/calibrationGradings/:calibrationSetId":"edit"},step:"calibrate"}),a.router=new a.Router({controller:i,parentRouter:n.router}),e.app.vent.trigger("router:initialized",a.router),a});
define('routers/ResultsRouting',["app/Assess","backbone","routers/AssessmentsRouting","controllers/ResultsController"],function(e,t,n,i){var a={};return a.Router=e.Router.extend({appRoutes:{"courses/:courseId/assessments/:assessmentId/results":"index","courses/:courseId/assessments/:assessmentId/results/mine":"showMine"},step:"results"}),a.router=new a.Router({controller:i,parentRouter:n.router}),e.app.vent.trigger("router:initialized",a.router),a});
require(["app/Assess","jquery","underscore","backbone","marionette","routers/CoursesRouting","routers/AssessmentsRouting","routers/SubmissionsRouting","routers/TrainingSetsRouting","routers/PeerGradingSetsRouting","routers/SelfGradingSetsRouting","routers/CalibrationSetsRouting","routers/ResultsRouting"],function(e,t,n,i){e.app.on("start",function(){t.ajaxSetup({timeout:9e4}),t(document).ready(function(){window.Eventing.setKeyPrefix("hg"),window.Eventing.bindToAllHtmlControls()}),i.history.start(n.extend({pushState:!0},e.BACKBONE_ROOT?{root:e.BACKBONE_ROOT}:{}))}),e.app.start()},function(e){var t="RequireJS error: "+e;console.error?console.error(t,e):console.log?console.log(t,e):window.alert(e)});
define("app/hg", function(){});
